Skip to content

Save Sync through a folder or the AnyTogether cloud, and Cloud Storage - #43

Merged
utkuhalis merged 10 commits into
mainfrom
parity/saves
Nov 1, 2026
Merged

utkuhalis merged 10 commits into
mainfrom
parity/saves

Conversation

@utkuhalis

Copy link
Copy Markdown
Collaborator

Brings the Mac launcher's Save Sync and AnyTogether cloud saves to the Windows and Linux launcher. It also wires up the profile "syncing" refusal, which nothing set before.

Through a folder (lib/core/save_sync.dart) ports the Mac's SaveSync.swift file for file. The folder holds AnyPS5/Saves/<title ID>/saves.zip, info.json with the Mac's date, digest and mac keys, and Older/. The digest is computed byte for byte the Mac's way, so a Mac and a PC can share one OneDrive, Dropbox or Syncthing folder. Profiles after the first get their own folder, as on the Mac. iCloud Drive is the default folder only where iCloud for Windows made %USERPROFILE%\iCloudDrive.

Through AnyTogether (lib/core/together/cloud_saves.dart) ports TogetherCloudSave.swift and the storage calls from AnyTogether's docs/cloud-storage.md:

  • uploads go in parts and resume, and a resumed upload sends only the missing parts;
  • a conflict found at begin or at complete asks the player, and keeping this computer's saves completes the same upload again;
  • a full quota asks before replacing the newest version;
  • downloads resume with Range and are checked by their SHA-256.

The slot (AnyPS5 saves) and the record are the Mac's.

Not available: GET /storage is asked at start and at sign-in. A server without storage, or a 503 storage_disabled answer, hides Sync Through and Cloud Storage, and nothing syncs through the cloud.

In the launcher (lib/ui/save_sync_model.dart):

  • Saves sync before a game starts and after it ends. With Save Sync off, a game starts at once as before.
  • While saves sync, the game does not start twice and the profile cannot be switched (ProfileRefusal.syncing).
  • Settings › Behaviour has Save Sync, Sync Through (when the cloud is available), Sync Folder and Cloud Storage. The keys are the Mac's: saveSync, syncFolder and syncThrough, kept per profile as on the Mac.
  • The cloud's questions show as a small panel. The focus starts on the first answer, and Back gives Not Now or Cancel.
  • Cloud Storage shows the usage and each game's versions, with Restore (which also brings the saves down here) and Delete (press twice).
  • Not ported: the media list on the Cloud Storage page and the Mac's usage bar. The usage is a line of text.
  • X-Part-SHA256 is not sent with parts. The docs say it is optional, and the account's upload call takes no extra headers.

Tests:

  • test/core/save_sync_test.dart has the Mac's SaveSyncTests and TogetherCloudSaveTests cases, run on a pretend cloud (test/support/fake_cloud.dart).
  • test/ui/save_sync_test.dart covers the settings rows, a sync before start and after the game ends, the syncing refusal, the question and its Back, and Cloud Storage restore and delete.
  • test/ui/save_sync_golden_test.dart adds a new cloud_conflict golden, which I checked.

…loud Storage

The Mac's SaveSync and TogetherCloudSave in Dart, file for file and on the same slot: a folder
(OneDrive, Dropbox, Syncthing, a shared drive, iCloud Drive where iCloud for Windows set it up) or
the AnyTogether cloud, before a game starts and after it ends. The question when both sides
changed or the quota is full, the syncing flag that keeps the profile and a second start, a
server without storage hiding the cloud rows, Cloud Storage with each game's versions, Restore
and Delete.
# Conflicts:
#	assets/l10n/en.json
#	assets/l10n/tr.json
#	lib/ui/app_model.dart
# Conflicts:
#	RELEASE_NOTES.md
#	assets/l10n/en.json
#	assets/l10n/tr.json
# Conflicts:
#	RELEASE_NOTES.md
#	lib/ui/app_model.dart
# Conflicts:
#	RELEASE_NOTES.md
#	lib/ui/app_model.dart
#	lib/ui/panels.dart
# Conflicts:
#	RELEASE_NOTES.md
#	assets/l10n/en.json
#	assets/l10n/tr.json
#	lib/ui/app_model.dart
@utkuhalis
utkuhalis merged commit 8072da8 into main Nov 1, 2026
5 checks passed
@utkuhalis
utkuhalis deleted the parity/saves branch November 1, 2026 04:53
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