Skip to content

feat(saves): restore a save directly from a USB drive on the PS5#167

Open
Twice6804 wants to merge 1 commit into
phantomptr:mainfrom
Twice6804:feat/restore-saves-from-usb
Open

feat(saves): restore a save directly from a USB drive on the PS5#167
Twice6804 wants to merge 1 commit into
phantomptr:mainfrom
Twice6804:feat/restore-saves-from-usb

Conversation

@Twice6804

Copy link
Copy Markdown
Contributor

Description

Mirrors the "Save to USB" feature (83ea617) with a Restore from USB action on the Saves screen — both per-row and bulk.

Reads the latest timestamped backup zip from `/<title_id>//<title_id>.zip` on a USB / extended-storage drive plugged into the PS5, validates it in a host temp dir, then wipes and re-uploads the live save — no PC round-trip needed.

Type of Change

  • New feature (non-breaking change which adds functionality)

Changes Made

  • `client/src/screens/Saves/index.tsx` — `resolveLatestUsbBackup` helper (lists the title dir, picks the lexically-greatest timestamp folder); `restoreOneFromUsb` core (preflight → resolve → confirm → download zip off USB → unzip → restore-prepare → stale-host guard → wipe → upload); `handleRestoreFromUsb` per-row wrapper; `handleRestoreAllFromUsb` bulk handler (single up-front confirm, skips games with no backup rather than failing them); per-row "Restore from USB" button (`danger` variant); "Restore all from USB" bulk header button; both bulk ops cross-disable each other.
  • `client/src/i18n/locales/en.ts` — 12 new `saves_restore_usb_*` keys.
  • `scripts/i18n-known-missing.json` — all 12 new keys added to the `missing` list for all 17 non-English locales (same pattern as the backup keys).

Documentation Updates

Did you update the documentation? [x] No

No docs changes needed — the feature is a direct mirror of "Save to USB" which also had no dedicated doc entry.

Testing

  • My code follows the project's style guidelines
  • I have performed a self-review of my own code

Hardware testing checklist (requires a PS5 with USB drive):

  • Back up a save to USB with the existing button, confirm `/<title_id>//<title_id>.zip` exists.
  • Click Restore from USB on that game → confirm dialog shows the timestamp → live save is wiped and re-uploaded → success toast.
  • Create a second, newer backup; Restore from USB again → confirm it picks the newer timestamp.
  • Click Restore all from USB → single confirm → summary counts are correct; a game with no USB backup is listed as skipped, not failed.
  • Unplug USB / point save path at a bad mount → verify the no-volume error.

No backend/engine changes — all commands reused from the existing restore and backup flows. The stale-host guard (present in `handleRestore` since 2.9.0) is carried over verbatim to prevent wipes against the wrong console if the user switches PS5 during the operation.

Additional Notes

The "latest backup" is resolved by sorting the timestamp directory names as strings — the `YYYY-MM-DD_HHMMSS` format produced by `backupTimestamp()` is documented as lexically sortable, so no mtime parsing is needed.

Mirrors the "Save to USB" feature (83ea617) with a "Restore from USB"
action (per-row + bulk) on the Saves screen. Reads the latest timestamped
zip from <savePath>/<title_id>/<timestamp>/<title_id>.zip on a USB /
extended-storage drive plugged into the PS5, validates and unzips it in
a host temp dir, then wipes and re-uploads the live save — no PC round-
trip needed.

Resolves "latest" by listing the title_id directory and picking the
lexically-greatest timestamp folder (the YYYY-MM-DD_HHMMSS format from
backupTimestamp() is documented as lexically sortable).

Per-row "Restore from USB" confirms with the resolved timestamp before
wiping. Bulk "Restore all from USB" confirms once up front; games with
no backup on the USB drive are skipped and reported in the summary
separately from failures.

Reuses all existing backend commands (transfer_download, save_archive_
unzip, save_archive_restore_prepare, fs_list_dir, fs_delete,
transfer_dir); no payload/engine changes required. Carries the same
stale-host guard as handleRestore to prevent wipes against the wrong
console if the user switches PS5 during the operation.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@Twice6804 Twice6804 requested a review from phantomptr as a code owner July 3, 2026 02:06
@Twice6804

Copy link
Copy Markdown
Contributor Author

@phantomptr Added the restore saves from usb functionality requested in #144

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant