mirror of
https://github.com/quer3q/ps5-dump-forge.git
synced 2026-10-18 19:49:54 -05:00
Release v0.3.0
This commit is contained in:
1 parent
71dd1f88bb
commit
1a410d3c8f
21 files changed
+71
-64
No files matched your search
@@ -56,7 +56,7 @@ write safety); `docs/LZ4.md` the LZ4 user guide.
|
||||
over `sevenz-rust2` (decode only), `rar.rs` our FFI wrapper over `unrar_sys` (bundles UnRAR's C++; every target,
|
||||
the PS5 payload included), `parts.rs` multi-part naming, `stream.rs` the `Reader`. Glue: `core/src/archive.rs` (`ArchiveTree`), `inspect.rs`,
|
||||
`library::archive_game_root`. Licence: `vendor/LICENSE-UnRAR.txt`, `vendor/LICENSE-UnRAR-exception.md` (copied into every release).
|
||||
- `crates/ps5-dump-forge-cli`: binary `ps5-dump-forge` (`inspect`, `convert`, `serve`), JSON-lines events.
|
||||
- `crates/ps5-dump-forge-cli`: binary `ps5-dump-forge` (`inspect`, `convert`, `lz4-patch`, `lz4-unpatch`, `serve`), JSON-lines events.
|
||||
- `crates/ps5-dump-forge-ps5`: the payload's global allocator (`Pool`, installed by the CLI only for
|
||||
the PS5): freed blocks of 64 B..4 MiB kept in power-of-two classes, since the PS5 libc serializes
|
||||
every malloc across threads (a `.pkg`'s Kraken pool: 12.7 → 49.3 MB/s at 4 threads).
|
||||
@@ -237,8 +237,10 @@ write safety); `docs/LZ4.md` the LZ4 user guide.
|
||||
`.pkg` are read-only on the console; on the PS5 an image ShadowMount+ has mounted or one inside
|
||||
`/mnt/shadowmnt`, `smp_finding`, in preflight and again before the replace). `output` is ignored: the job writes `<source>.<job>-<pid>.part`
|
||||
beside the source (the destination check counts the whole new image), verifies it as usual, re-checks
|
||||
the source's `SourceStamp`, closes the source and renames the part over it (`Part::replace`, one
|
||||
atomic rename, folder synced). Any failure leaves the source byte-identical and the `.part` deleted.
|
||||
the source's `SourceStamp`, closes the source and puts the part in its place (`Part::replace`: the original kept as
|
||||
`*.orig.part` (a hard link, or a rename where the volume has none), folder synced, the part renamed over
|
||||
the source, folder synced, the backup removed). Any failure leaves the source byte-identical and the
|
||||
`.part` deleted (where putting the original back fails, the error names its `*.orig.part` backup).
|
||||
The server's stale-part filter takes an in-place job's `.part` from its source.
|
||||
3. Deleting the Edit tab's source, a Library entry or a File explorer row (the trash button of the Edit
|
||||
card, of a Library card/row or of an explorer row, or its Delete key; one **No** / **Yes, delete**
|
||||
@@ -434,7 +436,8 @@ write safety); `docs/LZ4.md` the LZ4 user guide.
|
||||
`/private/tmp`, ...; Linux `/proc`, `/usr`, `/run` except `/run/media/…`, ...; Windows, Program Files,
|
||||
... on the system drive). A path at or inside the canonical home is allowed first (a `/var/home/me` or
|
||||
`/root` home works). Everything else is allowed (home and its children, `/Volumes`, `/media`, `/mnt`,
|
||||
volume and drive roots). `library_cover` refuses only links, devices and `/mnt/shadowmnt`.
|
||||
volume and drive roots). `library_cover` refuses links, devices, `/mnt/shadowmnt`, a file
|
||||
without one of the five image extensions and an image on another filesystem than its folder.
|
||||
Walk exclusions: 12 skip names, the home's app-data folder, `.part`, non-UTF-8 names.
|
||||
- **Limits** (`library.rs`): depth 6 (root 0), 20,000 directories and 200,000 entries per root, 10,000
|
||||
entries per directory, 256 image opens, 2,000 games, 15 s budget, 20 warnings; hitting one sets
|
||||
@@ -497,7 +500,7 @@ write safety); `docs/LZ4.md` the LZ4 user guide.
|
||||
FPKG is labelled `fpkg`; its files, the `Format`/`Kind` id and the CLI flag stay `pkg`. Format copy and
|
||||
the About tab's formats table (`app/src/Formats.tsx`) follow ShadowMountPlus 1.7's README and release notes.
|
||||
About's feature list (`formats.features`: bold name + a few words) is the user's text (by user decision):
|
||||
Convert, Edit, Delete, LZ4 "with smart healing", Streamed, Archives, Library, Safe, USB and SD cards, In
|
||||
Convert, Edit, Delete, LZ4 "with smart healing", Streamed, Archives, Storage (Library + File explorer), Safe, USB and SD cards, In
|
||||
place or rebuilt; sized so the card matches the QR card's height at 1200px; every language translates it.
|
||||
- UI languages: English (the fallback), Russian, Simplified Chinese (`zh`), German, Spanish, French,
|
||||
Japanese, Brazilian Portuguese (`pt`), Italian, Korean and Arabic; UI text only (`app/src/i18n.ts`). Backend text
|
||||
|
||||
Generated
+12
-12
@@ -2458,7 +2458,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ps5-dump-forge-archive"
|
||||
version = "0.2.0"
|
||||
version = "0.3.0"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"crc32fast",
|
||||
@@ -2471,7 +2471,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ps5-dump-forge-cli"
|
||||
version = "0.2.0"
|
||||
version = "0.3.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"libc",
|
||||
@@ -2483,7 +2483,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ps5-dump-forge-core"
|
||||
version = "0.2.0"
|
||||
version = "0.3.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"blake3",
|
||||
@@ -2506,7 +2506,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ps5-dump-forge-exfat"
|
||||
version = "0.2.0"
|
||||
version = "0.3.0"
|
||||
dependencies = [
|
||||
"ps5-dump-forge-patch",
|
||||
"ps5upload-fpkg",
|
||||
@@ -2515,14 +2515,14 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ps5-dump-forge-fpkg"
|
||||
version = "0.2.0"
|
||||
version = "0.3.0"
|
||||
dependencies = [
|
||||
"ps5upload-fpkg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ps5-dump-forge-gui"
|
||||
version = "0.2.0"
|
||||
version = "0.3.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"dunce",
|
||||
@@ -2535,7 +2535,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ps5-dump-forge-lz4"
|
||||
version = "0.2.0"
|
||||
version = "0.3.0"
|
||||
dependencies = [
|
||||
"blake3",
|
||||
"crc32fast",
|
||||
@@ -2547,14 +2547,14 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ps5-dump-forge-patch"
|
||||
version = "0.2.0"
|
||||
version = "0.3.0"
|
||||
dependencies = [
|
||||
"crc32fast",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ps5-dump-forge-pfs"
|
||||
version = "0.2.0"
|
||||
version = "0.3.0"
|
||||
dependencies = [
|
||||
"flate2",
|
||||
"ps5-dump-forge-exfat",
|
||||
@@ -2565,11 +2565,11 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ps5-dump-forge-ps5"
|
||||
version = "0.2.0"
|
||||
version = "0.3.0"
|
||||
|
||||
[[package]]
|
||||
name = "ps5-dump-forge-server"
|
||||
version = "0.2.0"
|
||||
version = "0.3.0"
|
||||
dependencies = [
|
||||
"dunce",
|
||||
"flate2",
|
||||
@@ -2584,7 +2584,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ps5-dump-forge-ufs2"
|
||||
version = "0.2.0"
|
||||
version = "0.3.0"
|
||||
dependencies = [
|
||||
"ps5-dump-forge-patch",
|
||||
"ps5upload-fpkg",
|
||||
|
||||
+1
-1
@@ -22,7 +22,7 @@ resolver = "3"
|
||||
[workspace.package]
|
||||
edition = "2024"
|
||||
license = "GPL-3.0-or-later"
|
||||
version = "0.2.0"
|
||||
version = "0.3.0"
|
||||
rust-version = "1.99"
|
||||
|
||||
[workspace.dependencies]
|
||||
|
||||
@@ -58,7 +58,7 @@ gradient notice bar) and the app icon (near-black navy with a blue edge and an o
|
||||
| ffpfs | `fmt-ffpfs` | teal `#7ee0e0` |
|
||||
| ffpfsc | `fmt-ffpfsc` | amber `#ffc580` |
|
||||
| fpkg | `fmt-pkg` | green `#8fe0ab` (Convert's default target) |
|
||||
| LZ4 packed folder | `fmt-lz4` | lime `#d6e875` (only the LZ4 tab's Pack target picker offers it) |
|
||||
| LZ4 packed folder | `fmt-lz4` | lime `#d6e875` (a job row's pill for a Pack into a folder; the Pack target picker shows that target as Folder) |
|
||||
|
||||
**Semantic tags.** Tinted pills for states: `.tag.blue` Writing, `.tag.green` Done, `.tag.red` Failed,
|
||||
`.tag.orange` Backport, `.tag.violet` DLC and Additional content (a source without `eboot.bin`, beside
|
||||
@@ -300,8 +300,8 @@ tiles and tags. Two columns from 880px; Edit splits 1:2 from 1100px (its game ca
|
||||
shows the red reason and a `.small` **Enter password** (lock icon) in `.row.locked`. The password
|
||||
stays in memory with that source (inspect, naming and its jobs), never stored or shown.
|
||||
- **Delete** (`confirmDelete` in `delete.tsx`, `role="alertdialog"`, shared by Edit, the Library and
|
||||
the File explorer): the warn icon, "Delete this folder?" / "Delete this image?" (the explorer: also
|
||||
"Delete this file?"), the whole path in an
|
||||
the File explorer): the trash icon in the warn amber (`.head-icon.warn`), "Delete this folder?" / "Delete this image?" /
|
||||
"Delete this archive?" (the explorer: also "Delete this file?"), the whole path in an
|
||||
`.out-box`, a muted line (for good, no Trash or undo), and two buttons: **No** (focused first) and
|
||||
**Yes, delete** (`.danger`). Afterwards a muted "Deleted <path>".
|
||||
|
||||
@@ -341,8 +341,8 @@ tiles and tags. Two columns from 880px; Edit splits 1:2 from 1100px (its game ca
|
||||
"Skipped locations and files" fold. No roots: "No folders are available to scan."
|
||||
- **File explorer** (`Files.tsx`, `.explorer.files`): Edit's explorer card (head with the folder icon,
|
||||
"File explorer", on a computer the root's `PathLine`, **Refresh**, **Choose folder**; Up and
|
||||
crumbs, the filter and count, the `xgrid` well) without a pending bar: a muted info line says changes
|
||||
happen at once. Row actions, icon-only (`aria-label` + `title`): Rename (pencil; inline name input, F2),
|
||||
crumbs, the filter and count, the `xgrid` well) without a pending bar: an info `.note-line` (`.explorer-note`, `--fg-2`) says
|
||||
changes happen at once. Row actions, icon-only (`aria-label` + `title`): Rename (pencil; inline name input, F2),
|
||||
Move to (the `move` icon; the folder picker), Delete (trash, `.danger`), then for a folder or an
|
||||
image/archive a ⋯ (`dots`) `ChooseMenu` with Edit and Convert ("More actions for <name>"; it opens
|
||||
upwards, or from its other edge, where the well would clip it: `.menu.up`, `.menu.start`), then a
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<p align="center"><img src="app/src-tauri/icons/128x128@2x.png" width="128" alt="PS5 Dump Forge"></p>
|
||||
|
||||
Runs on everything (including your PS5) and converts everything: **folder**, **exfat**, **ffpfs**, **ffpfsc**, **pkg**.
|
||||
Runs on everything (including your PS5), converts and edits everything: game `folders`, `exfat`, `ffpkg`, `ffpfs`,
|
||||
`ffpfsc` and debug `FPKG` packages, straight from `zip`, `7z` and `rar` too, with experimental `LZ4` asset packs for AMPR games.
|
||||
|
||||
Can utilize LZ4 compression and unpack archives (**zip**/**7zip**/**rar**).
|
||||
|
||||
The interface is in **11 languages**.
|
||||
|
||||
@@ -28,11 +28,11 @@ The interface is in **11 languages**.
|
||||
## Formats
|
||||
|
||||
Images are mounted by [ShadowMountPlus](https://github.com/drakmor/ShadowMountPlus); the debug FPKG is
|
||||
installed. Every format can be created and read back (an image or `.fpkg` can be extracted to a folder).
|
||||
installed. Every format can be created and read back (an image or a debug FPKG `.pkg` can be extracted to a folder).
|
||||
|
||||
| Format | Console speed | Size on disk | Notes |
|
||||
|---|---|---|---|
|
||||
| `.fpkg` (debug FPKG, saved as `.pkg`) | Native, full speed | 30–60% less, depending on the game | Installs on firmware 11.60 or lower with kstuff + fpkg-enable + ppr-patch. Kraken level (`--kraken`): **Fast** (default), **Balanced** / **Smallest** ≈ 2.6% smaller at ~6× / ~9× the compression time, **Stored** uncompressed (for a console that installs a compressed package but won't start it). Reads packages from this builder and compatible debug builders. |
|
||||
| `.fpkg` (debug FPKG, saved as `.pkg`) | Native, full speed | 30–60% less, depending on the game | Installs on firmware 11.60 or lower. Reads packages from this builder and compatible debug builders. |
|
||||
| `.ffpkg` (UFS2) | Full image speed | Equal to the game size | ShadowMountPlus's recommendation. |
|
||||
| `.exfat` (512 B sectors, 64 KiB clusters) | Full image speed | Equal to the game size | For games that only run like external-drive content. |
|
||||
| `.ffpfs` (PFS, uncompressed) | Full image speed | Equal to the game size | Experimental in ShadowMountPlus. ASCII file names only. |
|
||||
@@ -54,24 +54,21 @@ Before you press Apply the tab says how the changes will go in:
|
||||
marked unclean, or a `.ffpkg` not laid out the way Forge writes one, takes Rebuild instead. If the check after writing fails, or the computer or console stops part way, the image is put back
|
||||
from an undo file beside it (`<image>.forge-undo`); one left by a crash is restored on the next edit.
|
||||
- **Rebuild**: a new image of the same format is written beside the original from the original plus your
|
||||
changes, verified, then put in its place. It needs about the image's size of free space beside it. It is
|
||||
changes, verified, then put in its place. It needs free space beside the original for the new image (the tab says how much: for `.ffpfsc` and `.pkg`
|
||||
it can be more than the original's size). It is
|
||||
the only way for `.ffpfsc` and `.pkg`, and the way when the changes don't fit in place.
|
||||
|
||||
A folder is changed directly, with no undo: a failure part way leaves the earlier changes in. Archives can be
|
||||
browsed and extracted from, not edited; a game with LZ4 packs must be unpacked first. For an AMPR title, a change to its file
|
||||
list writes a fresh `ampr_emu.index` and drops the old traces; the ampr_emu runtime is left as it is. On the
|
||||
PS5, an image ShadowMountPlus has mounted can't be edited: stop the game and move the image out of
|
||||
ShadowMountPlus's folders (or turn it off) first. In a browser on another device, dropped files are uploaded to the console
|
||||
when you press Apply, so they need that much free space beside the game until the job ends. Close the game
|
||||
before applying; once applied there is no undo.
|
||||
|
||||
**Extract** copies a file or folder (a row's Extract button, or **Extract folder** for the folder shown, the
|
||||
whole game at the top) out of any source, images, `.pkg` and archives included, into a folder you choose.
|
||||
Nothing there is ever replaced: a name that already exists stops it before anything is copied.
|
||||
|
||||
A source with a `sce_sys/param.json` naming a title ID but no `eboot.bin` is **additional content** (a DLC, an update or
|
||||
another package) and is labelled so everywhere. It can be edited and extracted like a game, and converted
|
||||
to a folder or an `.fpkg` (not to an image).
|
||||
## Storage
|
||||
|
||||
The **Storage** tab holds the **Library** (the games found in a folder you choose, or on the PS5's drives)
|
||||
and a **File explorer**. Both open a game in Edit or Convert. The File explorer renames, moves and deletes at
|
||||
once, after you confirm: a delete is permanent (no Trash), a move stays on the same drive and never replaces
|
||||
anything, and anything an unfinished job uses is refused. On the PS5, images ShadowMountPlus has mounted are
|
||||
tagged **Mounted** in the File explorer and can't be edited, moved or deleted.
|
||||
|
||||
## LZ4 asset packs
|
||||
|
||||
@@ -91,6 +88,12 @@ Without traces or a profile, Pack falls back to a built-in guess of which files
|
||||
ampr_emu 0.4.2.1 is an upstream test build: some games crash when saving. Details, CLI options and
|
||||
caveats: [docs/LZ4.md](docs/LZ4.md).
|
||||
|
||||
A plain conversion (Convert, or the CLI without LZ4 options) also repairs an AMPR title: it installs the bundled
|
||||
ampr_emu where there is none, replaces an older, unknown or trace build, and writes a fresh `ampr_emu.index` when
|
||||
the old one doesn't match the files written, dropping the old traces and logs with it (into a `.pkg`, the package
|
||||
builder writes the index). An LZ4-packed source keeps its index, traces and logs as they are. Convert says up
|
||||
front what it will do.
|
||||
|
||||
## Download and run
|
||||
|
||||
Every release archive on the Releases page holds the app and the `ps5-dump-forge` command-line tool. Nothing to install; the app writes nothing beyond its own
|
||||
@@ -102,7 +105,7 @@ WebView data, so keep it in any folder you can write to.
|
||||
(`nc -w 3 <ps5-ip> 9021 < ps5-dump-forge-<version>-ps5.elf`), or list it in an autoloader's
|
||||
`autoload.txt`. A notification says Dump Forge is launched; open it from its icon.
|
||||
- **Open the UI** from the Dump Forge icon, or in any browser on the same network:
|
||||
`http://<ps5-ip>:8095`.
|
||||
`http://<ps5-ip>:8095`. In the console's browser, **L2** / **R2** switch tabs.
|
||||
|
||||
### macOS (11 or later)
|
||||
|
||||
|
||||
Generated
+2
-2
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "forge-app",
|
||||
"version": "0.2.0",
|
||||
"version": "0.3.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "forge-app",
|
||||
"version": "0.2.0",
|
||||
"version": "0.3.0",
|
||||
"license": "GPL-3.0-or-later",
|
||||
"dependencies": {
|
||||
"@tauri-apps/api": "~2.12.1",
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
"name": "forge-app",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"version": "0.2.0",
|
||||
"version": "0.3.0",
|
||||
"license": "GPL-3.0-or-later",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"$schema": "https://schema.tauri.app/config/2",
|
||||
"productName": "PS5 Dump Forge",
|
||||
"mainBinaryName": "PS5 Dump Forge",
|
||||
"version": "0.2.0",
|
||||
"version": "0.3.0",
|
||||
"identifier": "io.github.quer3q.ps5-dump-forge",
|
||||
"build": {
|
||||
"beforeDevCommand": "npm run dev",
|
||||
|
||||
@@ -164,7 +164,7 @@ const ar: Messages = {
|
||||
["LZ4", "تتبّع لعبة تستخدم AMPR ثم حزم أصولها مع إصلاح ذكي (تجريبي)."],
|
||||
["بالتدفّق", "من أي مصدر إلى أي وجهة: بلا نسخة مؤقتة، حتى للصورة داخل ffpfsc أو اللعبة داخل أرشيف."],
|
||||
["الأرشيفات", "ملف .zip أو .7z أو .rar يضم لعبة يُتصفَّح ويُحوَّل ويُحزَم كأنه مجلد."],
|
||||
["المكتبة", "الألعاب على هذا الحاسوب أو الجهاز، جاهزة للتحويل والتحرير."],
|
||||
["التخزين", "مكتبة لألعابك ومستكشف الملفات لإعادة التسمية والنقل والحذف."],
|
||||
["آمن", "لا تتغير لعبتك أبدًا ما لم تطلب ذلك؛ تُتجاوز الملفات غير المفيدة وتُبلَّغ أسماء الملفات السيئة مسبقًا."],
|
||||
["USB وبطاقات SD", "يُكتب على الذاكرات والبطاقات المهيأة بنظام exFAT أو FAT32."],
|
||||
["في مكانه أو بإعادة بناء", "تدخل التعديلات مباشرة في الصورة إن كانت تتسع، وإلا في صورة جديدة تحل محلها بعد التحقق."],
|
||||
|
||||
@@ -123,7 +123,7 @@ const de: Messages = {
|
||||
["LZ4", "Tracing eines AMPR-Spiels, dann Packen seiner Assets mit intelligenter Reparatur (experimentell)."],
|
||||
["Gestreamt", "von jeder Quelle zu jedem Ziel: ohne temporäre Kopie, auch für das Image in einem ffpfsc oder ein Spiel in einem Archiv."],
|
||||
["Archive", "ein .zip, .7z oder .rar mit einem Spiel wird wie ein Ordner durchsucht, konvertiert oder gepackt."],
|
||||
["Bibliothek", "die Spiele auf diesem Computer oder dieser Konsole, bereit zum Konvertieren und Bearbeiten."],
|
||||
["Speicher", "eine Bibliothek Ihrer Spiele und ein Datei-Explorer zum Umbenennen, Verschieben und Löschen."],
|
||||
["Sicher", "Ihr Spiel wird nie verändert, außer Sie wünschen es; Müll-Dateien werden übersprungen, ungültige Dateinamen vorab gemeldet."],
|
||||
["USB und SD-Karten", "geschrieben auf Sticks und Karten mit exFAT oder FAT32."],
|
||||
["An Ort und Stelle oder neu gebaut", "Änderungen gehen direkt ins Image, wenn sie passen, sonst in ein neues Image, das es nach der Prüfung ersetzt."],
|
||||
|
||||
@@ -134,7 +134,7 @@ const en = {
|
||||
["LZ4", "trace an AMPR game, then pack its assets with smart healing (experimental)."],
|
||||
["Streamed", "from any source to any target: no temporary copy, not even the image inside an ffpfsc or a game in an archive."],
|
||||
["Archives", "a .zip, .7z or .rar holding one game is browsed, converted or packed like a folder."],
|
||||
["Library", "the games on this computer or console, ready to convert and edit."],
|
||||
["Storage", "a Library of your games and a File explorer to rename, move and delete."],
|
||||
["Safe", "your game is never changed unless you ask; junk files are skipped and bad file names reported up front."],
|
||||
["USB and SD cards", "written onto sticks and cards formatted exFAT or FAT32."],
|
||||
["In place or rebuilt", "edits go straight into an image when they fit, else into a new image that replaces it once checked."],
|
||||
|
||||
@@ -137,7 +137,7 @@ const es: Messages = {
|
||||
["LZ4", "trazar un juego con AMPR y luego empaquetar sus recursos con reparación inteligente (experimental)."],
|
||||
["En streaming", "de cualquier origen a cualquier destino: sin copia temporal, ni siquiera para la imagen dentro de un ffpfsc o un juego en un archivo comprimido."],
|
||||
["Archivos comprimidos", "un .zip, .7z o .rar con un juego se explora, convierte o empaqueta como una carpeta."],
|
||||
["Biblioteca", "los juegos de este ordenador o consola, listos para convertir y editar."],
|
||||
["Almacenamiento", "una Biblioteca de tus juegos y un Explorador de archivos para renombrar, mover y eliminar."],
|
||||
["Seguro", "tu juego nunca cambia salvo que lo pidas; los archivos basura se omiten y los nombres de archivo incorrectos se avisan de antemano."],
|
||||
["USB y tarjetas SD", "se escribe en memorias y tarjetas formateadas en exFAT o FAT32."],
|
||||
["En el sitio o reconstruido", "los cambios van directo a la imagen si caben; si no, a una imagen nueva que la reemplaza tras comprobarla."],
|
||||
|
||||
@@ -127,7 +127,7 @@ const fr: Messages = {
|
||||
["LZ4", "traçage d’un jeu AMPR, puis empaquetage de ses ressources avec réparation intelligente (expérimental)."],
|
||||
["En flux", "de n’importe quelle source vers n’importe quelle cible : sans copie temporaire, même pour l’image dans un ffpfsc ou un jeu dans une archive."],
|
||||
["Archives", "un .zip, .7z ou .rar contenant un jeu se parcourt, se convertit ou s’empaquette comme un dossier."],
|
||||
["Bibliothèque", "les jeux de cet ordinateur ou de cette console, prêts à convertir et à modifier."],
|
||||
["Stockage", "une Bibliothèque de vos jeux et un Explorateur de fichiers pour renommer, déplacer et supprimer."],
|
||||
["Sûr", "votre jeu n’est jamais modifié sans que vous le demandiez ; les fichiers parasites sont ignorés et les mauvais noms de fichiers signalés d’avance."],
|
||||
["USB et cartes SD", "écrit sur des clés et cartes formatées en exFAT ou FAT32."],
|
||||
["Sur place ou reconstruit", "les modifications vont directement dans l’image si elles tiennent, sinon dans une nouvelle image qui la remplace après vérification."],
|
||||
|
||||
@@ -133,7 +133,7 @@ const it: Messages = {
|
||||
["LZ4", "traccia un gioco AMPR, poi impacchettane gli asset con riparazione intelligente (sperimentale)."],
|
||||
["In streaming", "da qualsiasi origine a qualsiasi destinazione: senza copia temporanea, nemmeno per l’immagine dentro un ffpfsc o un gioco in un archivio."],
|
||||
["Archivi", "uno .zip, .7z o .rar con un gioco si sfoglia, converte o impacchetta come una cartella."],
|
||||
["Libreria", "i giochi su questo computer o console, pronti da convertire e modificare."],
|
||||
["Archiviazione", "una Libreria dei tuoi giochi ed Esplora file per rinominare, spostare ed eliminare."],
|
||||
["Sicuro", "il tuo gioco non cambia mai se non lo chiedi; i file spazzatura vengono saltati e i nomi di file errati segnalati in anticipo."],
|
||||
["USB e schede SD", "scritto su chiavette e schede formattate exFAT o FAT32."],
|
||||
["Sul posto o ricostruito", "le modifiche vanno direttamente nell’immagine se ci stanno, altrimenti in una nuova immagine che la sostituisce dopo il controllo."],
|
||||
|
||||
@@ -129,7 +129,7 @@ const ja: Messages = {
|
||||
["LZ4", "AMPR ゲームをトレースし、そのアセットをスマート修復付きでパックします(実験的)。"],
|
||||
["ストリーミング", "任意のソースから任意の出力先へ。一時コピーなしで、ffpfsc 内のイメージやアーカイブ内のゲームでも同様です。"],
|
||||
["アーカイブ", "ゲームを含む .zip、.7z、.rar をフォルダーのように閲覧、変換、パックできます。"],
|
||||
["ライブラリ", "このコンピューターまたは本体にあるゲームを、すぐに変換・編集できます。"],
|
||||
["ストレージ", "ゲームのライブラリと、名前の変更・移動・削除ができるファイルエクスプローラー。"],
|
||||
["安全", "依頼しない限りゲームは変更されません。ジャンクファイルはスキップし、不正なファイル名は事前に報告します。"],
|
||||
["USB と SD カード", "exFAT または FAT32 でフォーマットしたメモリーやカードに書き込めます。"],
|
||||
["その場で、または再構築", "収まる場合は編集をイメージに直接反映し、収まらない場合は新しいイメージを作り、検証後に置き換えます。"],
|
||||
|
||||
@@ -123,7 +123,7 @@ const ko: Messages = {
|
||||
["LZ4", "AMPR 게임을 트레이스한 다음 에셋을 스마트 복구와 함께 패킹합니다(실험적)."],
|
||||
["스트리밍", "어떤 원본에서 어떤 대상으로든 임시 복사본 없이 처리합니다. ffpfsc 안의 이미지나 아카이브 안의 게임도 마찬가지입니다."],
|
||||
["아카이브", "게임이 든 .zip, .7z, .rar 를 폴더처럼 탐색, 변환, 패킹합니다."],
|
||||
["라이브러리", "이 컴퓨터나 본체에 있는 게임을 바로 변환하고 편집할 수 있습니다."],
|
||||
["저장소", "게임 라이브러리와 이름 변경·이동·삭제를 할 수 있는 파일 탐색기."],
|
||||
["안전", "요청하지 않으면 게임을 절대 변경하지 않으며, 불필요한 파일은 건너뛰고 잘못된 파일 이름은 미리 알려 줍니다."],
|
||||
["USB 및 SD 카드", "exFAT 또는 FAT32로 포맷된 USB 메모리와 카드에 기록합니다."],
|
||||
["제자리 또는 재빌드", "수정 사항이 들어가면 이미지에 바로 반영하고, 아니면 새 이미지를 만들어 검증 후 교체합니다."],
|
||||
|
||||
@@ -129,7 +129,7 @@ const pt: Messages = {
|
||||
["LZ4", "rastrear um jogo AMPR e depois empacotar os assets dele com reparo inteligente (experimental)."],
|
||||
["Em streaming", "de qualquer origem para qualquer destino: sem cópia temporária, nem para a imagem dentro de um ffpfsc ou um jogo em um arquivo compactado."],
|
||||
["Arquivos compactados", "um .zip, .7z ou .rar com um jogo é explorado, convertido ou empacotado como uma pasta."],
|
||||
["Biblioteca", "os jogos deste computador ou console, prontos para converter e editar."],
|
||||
["Armazenamento", "uma Biblioteca dos seus jogos e um Explorador de arquivos para renomear, mover e excluir."],
|
||||
["Seguro", "seu jogo nunca é alterado a menos que você peça; arquivos inúteis são ignorados e nomes de arquivo inválidos são avisados antes."],
|
||||
["USB e cartões SD", "gravado em pendrives e cartões formatados em exFAT ou FAT32."],
|
||||
["No lugar ou refeito", "as edições vão direto na imagem quando cabem; senão, vão para uma nova imagem que a substitui depois de verificada."],
|
||||
|
||||
@@ -125,7 +125,7 @@ const ru: Messages = {
|
||||
["LZ4", "трейсинг игры с AMPR и упаковка её ресурсов с умным восстановлением (экспериментально)."],
|
||||
["Потоково", "из любого источника в любой приёмник: без временной копии, даже для образа внутри ffpfsc и игры в архиве."],
|
||||
["Архивы", "игра в .zip, .7z или .rar просматривается, конвертируется и упаковывается как папка."],
|
||||
["Библиотека", "игры на этом компьютере или консоли, готовые к конвертации и редактированию."],
|
||||
["Хранилище", "Библиотека ваших игр и Проводник, чтобы переименовывать, перемещать и удалять."],
|
||||
["Безопасно", "ваша игра не меняется без вашего запроса; мусорные файлы пропускаются, а плохие имена файлов выявляются заранее."],
|
||||
["USB и SD-карты", "запись на флешки и карты с exFAT или FAT32."],
|
||||
["На месте или с пересборкой", "правки вносятся прямо в образ, если помещаются, иначе в новый образ, который после проверки заменяет прежний."],
|
||||
|
||||
@@ -121,7 +121,7 @@ const zh: Messages = {
|
||||
["LZ4", "追踪 AMPR 游戏,再以智能修复方式打包其资源(实验性)。"],
|
||||
["流式", "可从任意来源到任意目标:无需临时副本,即使是 ffpfsc 内的镜像或压缩包中的游戏。"],
|
||||
["压缩包", "包含一款游戏的 .zip、.7z 或 .rar 可像文件夹一样浏览、转换或打包。"],
|
||||
["游戏库", "这台电脑或主机上的游戏,可直接转换和编辑。"],
|
||||
["存储", "您的游戏库,以及可重命名、移动和删除的文件浏览器。"],
|
||||
["安全", "除非您要求,否则绝不修改您的游戏;会跳过垃圾文件,并提前报告不合规的文件名。"],
|
||||
["USB 和 SD 卡", "可写入 exFAT 或 FAT32 格式的 U 盘和存储卡。"],
|
||||
["原位或重建", "能容纳时直接在镜像内编辑,否则生成新镜像,校验通过后替换原镜像。"],
|
||||
|
||||
+7
-7
@@ -84,10 +84,10 @@ FORGE_DEBUG_API=1 ps5/build.sh # bring-up only: adds POST /api/debug, GET /pro
|
||||
path confinement; paths go to core as given, as in the Tauri app. One delete route and one move route,
|
||||
by user decision (`delete_path`, Edit's and the Storage tab's; `move_path`, its File explorer's; the
|
||||
page's question authenticates nobody).
|
||||
- Limits: head 16 KiB, body 1 MiB (`Content-Length` only; `edit_upload` streams any size, 30 s idle per read), 10 s per request, 30 s per write (a download:
|
||||
- Limits: head 16 KiB, body 1 MiB (8 MiB for `start_job` and `edit_check`; `Content-Length` only; `edit_upload` streams any size, 30 s idle per read), 10 s per request, 30 s per write (a download:
|
||||
per 1 MiB chunk), 16 handler
|
||||
threads (then 503), 8 unfinished jobs (then 429), 2 inspections, naming, `host_tree` or `edit_check` requests at once (429,
|
||||
`Retry-After: 1`), 32 finished jobs and 200 log lines each kept, `list_dir` 10,000 entries (`truncated`),
|
||||
threads (then 503), 8 unfinished jobs (then 429), 2 source reads at once (inspections, naming, `host_tree`, `edit_check`,
|
||||
Library scans and covers; a further read waits up to 30 s for a slot, at most 4 waiting, then 429 `Retry-After: 1`), 32 finished jobs and 200 log lines each kept, `list_dir` 10,000 entries (`truncated`),
|
||||
`stale_parts` 1,000. `compression_threads: null` is `max(1, cores − 1)`; on the PS5
|
||||
`cores` is the payload's 5 CPUs (`compat.c`) and two are left free (3 workers), for the console's
|
||||
browser.
|
||||
@@ -105,8 +105,8 @@ FORGE_DEBUG_API=1 ps5/build.sh # bring-up only: adds POST /api/debug, GET /pro
|
||||
| `POST /api/start_job` | `{request: ConvertRequest}` | job id (`lz4_in_place: true` replaces an `.exfat`/`.ffpkg` source; `output` ignored; non-empty `edits` is an edit job of the source, in place or with `edit_rebuild`, `output` and `format` ignored; non-empty `extract` copies those game paths into the folder `output`, `format` `folder`) |
|
||||
| `POST /api/cancel_job` | `{id}` | `null` (idempotent) |
|
||||
| `POST /api/stale_parts` | `{dirs}` | `string[]`, without running jobs' parts (an in-place or edit job's beside its source) or a staging folder an upload or unfinished job uses |
|
||||
| `POST /api/edit_check` | `{request: ConvertRequest}` | `EditCheck {in_place, rebuild, needed_inside, free_inside, rebuild_needs, free_beside}`: why each mode can't apply (empty = it can) and the sizes (bytes, `null` where they don't apply); reads only, except that a leftover undo journal no job uses is restored first (after the ShadowMount+ check) and the U1 probe writes and removes its file. The source and every `Add.from` must be a folder or regular file (else 400); counts as an inspection (429), 409 once stopping |
|
||||
| `POST /api/host_tree` | `{path}` | `{kind: "file"\|"dir", size, files: [{path, size}], empty_dirs, truncated}`: a file or folder as an edit's add will read it (junk left out; a link or special file refused); `truncated` past 200,000 entries or 15 s. 404 missing, counts as an inspection (429), 409 once stopping, 500 with core's message |
|
||||
| `POST /api/edit_check` | `{request: ConvertRequest}` | `EditCheck {in_place, rebuild, needed_inside, free_inside, rebuild_needs, free_beside}`: why each mode can't apply (empty = it can) and the sizes (bytes, `null` where they don't apply); reads only, except that a leftover undo journal no job uses is restored first (after the ShadowMount+ check) and the U1 probe writes and removes its file. The source and every `Add.from` must be a folder or regular file (else 400); counts as an inspection (the 2-read cap), 409 once stopping |
|
||||
| `POST /api/host_tree` | `{path}` | `{kind: "file"\|"dir", size, files: [{path, size}], empty_dirs, truncated}`: a file or folder as an edit's add will read it (junk left out; a link or special file refused); `truncated` past 200,000 entries or 15 s. 404 missing, counts as an inspection (the 2-read cap), 409 once stopping, 500 with core's message |
|
||||
| `POST /api/edit_upload?source=&path=` | raw bytes (`Content-Length` required) | `{path}`: the staged file, `<source>.forge-upload-<pid>.part/<path>`, where the UI sends `path` as `<tag>-<k>/<game path>` (`stagingNames`: a random tag per Apply) (canonical source; folders made on demand, 0777 on the PS5), written to a temporary name and renamed over. 411 no length, 400 bad query, game path or a body that ended early or stalled, 404 source missing, 409 a non-file in the way, the same target uploading, an unfinished job using it, or stopping |
|
||||
| `POST /api/edit_discard` | `{source}` | `null`: the source's staging folder removed by `delete_path`'s rules (missing: `null`); 409 while an upload into it or a job using it is unfinished, or stopping |
|
||||
| `POST /api/lz4_patch` | `{source}` | `Lz4Patch`; 409 while a job is queued or running |
|
||||
@@ -114,10 +114,10 @@ FORGE_DEBUG_API=1 ps5/build.sh # bring-up only: adds POST /api/debug, GET /pro
|
||||
| `GET /api/lz4_traces?source=` | | both trace files as one zip download (below) |
|
||||
| `POST /api/delete_path` | `{path}` | `null`: the file or folder is gone for good (below); 400 refused, 404 missing, 409 a job uses it or stopping, 500 failed (a folder may be partly gone) |
|
||||
| `POST /api/move_path` | `{from, to}` | `null`: moved or renamed on its volume, `to` never replaced; `from` refused as `delete_path` refuses it (same roots kept), `to` refused inside `from`, on another drive, taken, or with an undo journal pending; 400 refused, 404 missing (source or target folder), 409 a job uses either or stopping, 500 failed |
|
||||
| `POST /api/library_scan` | `{}` (an object; `root` string scans just that folder on any filesystem (a network share included; a chosen root that is a link is resolved first, links inside the walk are never followed, `/mnt/shadowmnt` refused; system folders such as `/` or `/usr` are refused with core's message), non-string 400; `root` is required on a computer (400 "choose a folder to scan" without it) and optional on the PS5) | `{roots, entries: [{path, kind, title_id, title_name, version, has_cover, lz4_packed, additional_content}], truncated, warnings, storage?}`: the Library's scan of that folder, or on the PS5 of the server's current roots (browse roots without `/mnt/shadowmnt`, re-resolved each call so a newly attached drive appears on Refresh). `storage` `{free, total}` (bytes, `statfs` of `/data`) only on the PS5, read on each scan. Reads only; counts as an inspection (429 past 2), 409 once stopping, 500 with core's message. Partial results set `truncated` and add `warnings` (core's scan limits and 15 s cooperative budget). The request deadline governs receiving the request, not core's work, which can't be interrupted |
|
||||
| `POST /api/library_scan` | `{}` (an object; `root` string scans just that folder on any filesystem (a network share included; a chosen root that is a link is resolved first, links inside the walk are never followed, `/mnt/shadowmnt` refused; system folders such as `/` or `/usr` are refused with core's message), non-string 400; `root` is required on a computer (400 "choose a folder to scan" without it) and optional on the PS5) | `{roots, entries: [{path, kind, title_id, title_name, version, has_cover, lz4_packed, additional_content}], truncated, warnings, storage?}`: the Library's scan of that folder, or on the PS5 of the server's current roots (browse roots without `/mnt/shadowmnt`, re-resolved each call so a newly attached drive appears on Refresh). `storage` `{free, total}` (bytes, `statfs` of `/data`) only on the PS5, read on each scan. Reads only; counts as an inspection (the 2-read cap), 409 once stopping, 500 with core's message. Partial results set `truncated` and add `warnings` (core's scan limits and 15 s cooperative budget). The request deadline governs receiving the request, not core's work, which can't be interrupted |
|
||||
| `POST /api/library_cover` | `{path}` | a PNG data-URL string, or `null` (no icon, too large, not a PNG); fetched lazily per card. Same cap, 409 and 500 rules (an unreadable source is a 500) |
|
||||
| `POST /api/list_dir` | `{path: string\|null, explorer?: bool}` | `{path, parent, entries: [{name, path, dir, size, link, mounted}], truncated}` (`null`: the browse roots; `parent` `null` at a root; `link`: the entry is a link, its `path` the resolved target; with `explorer` the roots are the Library's, and on the PS5 `/mnt/shadowmnt` is hidden (a path in it 400) and `mounted` marks an image ShadowMount+ has mounted) |
|
||||
| `GET /api/jobs` | | `{instance, jobs: [{id, request, progress, done, log, log_total}]}` |
|
||||
| `GET /api/jobs` | | `{instance, jobs: [{id, request, stages, progress, done, log, log_total}]}` |
|
||||
| `POST /api/quit` | `{}` | `{}`, then cancels every job, waits for cleanup and exits |
|
||||
| `POST /api/quit` | `{"if_idle": true}` | `{}`, then exits as above, only when idle: 409 "Dump Forge is busy: …" while a job is queued or running, a `lz4_traces` download streams or a patch, delete or move holds admission past 1 s, 409 "Dump Forge is stopping" (the handover's request) |
|
||||
| `GET /api/elfldr` | — | `{up}`: elfldr accepts a connection (1 s; connect and close, nothing sent); 404 on a computer |
|
||||
|
||||
Vendored
+3
-2
@@ -11,7 +11,7 @@ inspection), taken from ps5upload with a small local patch series on top.
|
||||
| License | GPL-3.0-or-later (see `LICENSE-ps5upload`, and the note below) |
|
||||
| Edition | 2021, as upstream, on purpose: it keeps the diff to upstream small |
|
||||
|
||||
The trees here are upstream plus every patch in `patches/`, in order. Nothing else differs.
|
||||
The trees here are upstream plus every patch in `patches/` except 0021 (lzma-rust2, below), in order. Nothing else differs.
|
||||
|
||||
`LICENSE-UnRAR.txt` and `LICENSE-UnRAR-exception.md` are not vendored code: UnRAR's license and the
|
||||
GPLv3 §7 permission for the UnRAR source that `unrar_sys` (crates.io) builds into every target. The
|
||||
@@ -84,6 +84,7 @@ rm -rf /tmp/series && mkdir /tmp/series
|
||||
cp -R /tmp/ps5upload/engine/crates/ps5upload-fpkg /tmp/ps5upload/engine/crates/ps5upload-pkg /tmp/series/
|
||||
(cd /tmp/series && git init -q && git add -A && git commit -qm pristine)
|
||||
for p in patches/*.patch; do
|
||||
case $p in *0021-*) continue ;; esac
|
||||
(cd /tmp/series && git apply "$OLDPWD/$p" && git add -A && \
|
||||
git commit -qm "$(basename "$p" .patch | cut -d- -f2-)")
|
||||
done
|
||||
@@ -98,7 +99,7 @@ it on top. Then write every patch again, each against its parent:
|
||||
```sh
|
||||
cd /tmp/series && n=0
|
||||
for c in $(git rev-list --reverse HEAD~$(($(git rev-list --count HEAD) - 1))..HEAD); do
|
||||
n=$((n + 1))
|
||||
n=$((n + 1)); [ $n = 21 ] && n=22
|
||||
git diff --binary --histogram "$c~1" "$c" > "$OLDPWD/patches/$(printf %04d $n)-$(git log -1 --format=%s "$c" | tr ' ' -).patch"
|
||||
done
|
||||
```
|
||||
|
||||
Reference in new issue
Block a user