init
This commit is contained in:
@@ -0,0 +1,201 @@
|
||||
# PhotoSync
|
||||
|
||||
A Fabric client mod that sends your Minecraft screenshots to [Immich](https://immich.app)
|
||||
and lets you browse the album back inside the game.
|
||||
|
||||
Take a screenshot with F2 and it uploads in the background. Press F6 to see what
|
||||
is uploading, scroll through the album's timeline, or change how any of it
|
||||
behaves. Nothing about the vanilla screenshot flow changes — F2 still saves a PNG
|
||||
to `screenshots/` and still works with the mod misconfigured or offline.
|
||||
|
||||
Supports **Minecraft 1.20 through 26.2**, client side only. Requires
|
||||
[Fabric API](https://modrinth.com/mod/fabric-api).
|
||||
|
||||
---
|
||||
|
||||
## Install
|
||||
|
||||
1. Install Fabric Loader 0.19.3 or newer and Fabric API for your Minecraft
|
||||
version.
|
||||
2. Drop the jar matching your version into `mods/`:
|
||||
|
||||
| Your Minecraft version | Jar |
|
||||
| --- | --- |
|
||||
| 1.20 – 1.20.1 | `photosync-1.20.1-1.0.0.jar` |
|
||||
| 1.20.2 – 1.20.4 | `photosync-1.20.4-1.0.0.jar` |
|
||||
| 1.20.5 – 1.20.6 | `photosync-1.20.6-1.0.0.jar` |
|
||||
| 1.21 – 1.21.1 | `photosync-1.21.1-1.0.0.jar` |
|
||||
| 1.21.2 – 1.21.4 | `photosync-1.21.4-1.0.0.jar` |
|
||||
| 1.21.5 | `photosync-1.21.5-1.0.0.jar` |
|
||||
| 1.21.6 – 1.21.10 | `photosync-1.21.8-1.0.0.jar` |
|
||||
| 1.21.11 – 1.21.x | `photosync-1.21.11-1.0.0.jar` |
|
||||
| 26.1 – 26.2 | `photosync-26.2-1.0.0.jar` |
|
||||
|
||||
Each jar declares its own supported range, so Fabric will refuse to load the
|
||||
wrong one rather than crashing later.
|
||||
|
||||
3. Launch the game. PhotoSync does nothing until you connect it to a server.
|
||||
|
||||
The mod is client-side. Servers neither know nor care that you are running it,
|
||||
and it works in single player.
|
||||
|
||||
## Connect it to Immich
|
||||
|
||||
Press **F6** (rebindable in Options → Controls → PhotoSync), open **Settings**,
|
||||
and fill in two fields:
|
||||
|
||||
- **Server URL** — `https://photos.example.com`. Typing just `photos.example.com`
|
||||
works too; so does pasting a URL that already ends in `/api`.
|
||||
- **API key** — Immich's web UI, under Account Settings → API Keys. The field is
|
||||
masked, and the key is never written to the log or copied to the clipboard.
|
||||
|
||||
Press **Test**. It reports the account name and server version on success, and
|
||||
the actual failure on the way there — a wrong key and an unreachable host say
|
||||
different things.
|
||||
|
||||
Then pick an **Album**. "Whole library" uploads without adding to any album; the
|
||||
picker also creates one if you type a name and press Create. The chosen album is
|
||||
both where uploads go and what the Browse tab shows.
|
||||
|
||||
Settings save when you close the screen. **Revert** undoes everything since you
|
||||
opened it.
|
||||
|
||||
## The screens
|
||||
|
||||
**Uploads** is the queue: everything still in flight plus the last hundred that
|
||||
finished, newest first, each with its state — queued, uploading, retrying, done,
|
||||
failed — and a preview of the selected one. Failed uploads get a **Retry**;
|
||||
anything at all gets **Show in folder**, which opens `screenshots/` in your file
|
||||
manager. **Remove** takes an entry out of the list without touching the file, and
|
||||
**Clear finished** empties the completed ones in one go.
|
||||
|
||||
Uploads that fail retry on their own — five attempts by default, with the wait
|
||||
doubling each time, so the last one comes 80 seconds after the fourth. Only the
|
||||
final failure raises a corner message; the retries in between are visible here
|
||||
for anyone who wants to watch them.
|
||||
|
||||
**Browse** is the album, newest first, with a heading per day. It loads the way a
|
||||
photo website does: the per-day counts arrive before any image does, so the
|
||||
scrollbar is honest about the album's real size from the first frame, and the
|
||||
thumbnails for a day are fetched only when you scroll near them. Click a photo to
|
||||
open it larger, Escape to go back. It is read-only — PhotoSync will not delete,
|
||||
move or favourite anything on your server.
|
||||
|
||||
Videos in the album show their preview frame with a video badge in the corner.
|
||||
There is no playback; this is a screenshot mod.
|
||||
|
||||
**Settings** covers everything below.
|
||||
|
||||
## Automatic screenshots
|
||||
|
||||
Off by default, and it stays off until you turn it on. Once enabled, PhotoSync
|
||||
takes a screenshot every five minutes (adjustable from 5 seconds to an hour) and
|
||||
puts it through the same queue as a manual one.
|
||||
|
||||
- **Name suffix** — appended before `.png`, `_auto` by default, so an automatic
|
||||
capture lands as `2026-08-07_14.31.02_auto.png` and is easy to spot or filter.
|
||||
Leave it blank for none.
|
||||
- **Only while in a world** — on by default. No point photographing the main menu.
|
||||
- **Skip while a screen is open** — on by default. Your inventory is not a
|
||||
landscape.
|
||||
|
||||
Automatic captures are recorded separately from manual ones, so the two are
|
||||
distinguishable everywhere they appear.
|
||||
|
||||
## Messages in the corner
|
||||
|
||||
One line, bottom left, gone in three seconds. Separately switchable for
|
||||
screenshot taken, upload finished, and upload failed, with an adjustable
|
||||
duration — the setting that suits an automatic capture every thirty seconds is
|
||||
not the one that suits two screenshots an hour.
|
||||
|
||||
These draw on the in-world HUD, so they do not appear on the title screen or on
|
||||
top of an open screen. An upload that finishes while you are looking at the
|
||||
Uploads tab updates the list instead, which is better feedback than a toast.
|
||||
|
||||
## Quitting with uploads still running
|
||||
|
||||
If you quit while something is uploading, PhotoSync stops the shutdown and shows
|
||||
a progress dialog: how many are left, and two buttons. **Keep playing** returns
|
||||
you to the game. **Quit anyway** quits immediately.
|
||||
|
||||
Either way nothing is lost. The queue is on disk and is written through on every
|
||||
state change, so unfinished uploads resume the next time you play — the dialog
|
||||
exists to save you the wait, not to prevent a loss. An upload that was mid-flight
|
||||
when the game died is simply tried again, and Immich recognises the retry as a
|
||||
duplicate rather than storing a second copy.
|
||||
|
||||
You can turn the dialog off under Settings → Uploads → *Ask before quitting
|
||||
mid-upload*, in which case the game gets a three-second grace period to finish
|
||||
whatever is nearly done and then quits regardless.
|
||||
|
||||
## Everything else in Settings
|
||||
|
||||
| Setting | Default | |
|
||||
| --- | --- | --- |
|
||||
| Upload screenshots automatically | on | Off makes the mod a browser and a manual queue |
|
||||
| Uploads at once | 2 | Up to 4 |
|
||||
| Attempts before giving up | 5 | Up to 20 |
|
||||
| Wait between attempts | 5s | Doubles each attempt: 5s, 10s, 20s, 40s |
|
||||
| Delete the local file after upload | off | Only ever after the server confirms it |
|
||||
| Thumbnail size | 96px | 48–192 |
|
||||
| Thumbnails kept in memory | 256 | The mod's largest memory knob |
|
||||
| Mark videos in the grid | on | |
|
||||
|
||||
## Files it writes
|
||||
|
||||
Everything lives in `config/photosync/` in your game directory:
|
||||
|
||||
- `photosync.json` — settings, including your API key. Back it up accordingly.
|
||||
- `uploads.json` — the upload queue, so it survives a crash or a quit.
|
||||
|
||||
Screenshots themselves go where they always did, in `screenshots/`. PhotoSync
|
||||
never moves them, and only deletes one if you asked it to and the upload was
|
||||
confirmed.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
**"Not connected" on the Browse tab** — the server URL or API key is missing or
|
||||
wrong. Settings → Test says which.
|
||||
|
||||
**Screenshots are taken but nothing queues** — either *Upload screenshots
|
||||
automatically* is off, or there are no credentials yet. PhotoSync deliberately
|
||||
does not queue against a server it cannot reach, because the result is a list of
|
||||
failures you cannot act on.
|
||||
|
||||
**Thumbnails are blank in Browse** — Minecraft's image decoder reads PNG and JPEG
|
||||
only, and Immich's default thumbnail format is WebP. PhotoSync detects this and
|
||||
switches to JPEG previews for the rest of the session, so this should self-correct
|
||||
after the first few tiles.
|
||||
|
||||
**A jar refuses to load** — check the table above. Fabric enforces each jar's
|
||||
declared version range, so this means the jar is for a different bucket.
|
||||
|
||||
## Building from source
|
||||
|
||||
```sh
|
||||
./gradlew buildAllPlatforms
|
||||
```
|
||||
|
||||
Jars land in `platform/<version>/build/libs/`. Nothing is shaded or bundled —
|
||||
each jar is around 270 KB and contains only this mod's classes. To run one
|
||||
version in a dev client:
|
||||
|
||||
```sh
|
||||
./gradlew :platform:1.21.11:runClient
|
||||
```
|
||||
|
||||
The source tree is one shared implementation plus nine thin per-version
|
||||
adapters. If you are adding a Minecraft version or wondering why the layout is
|
||||
the way it is, [`docs/PORTING.md`](docs/PORTING.md) is the document for that: it
|
||||
covers the bucket scheme, the measured API breakpoints between every supported
|
||||
version, and the procedure for a new release.
|
||||
|
||||
Adding a photo service other than Immich means implementing `PhotoProvider` and
|
||||
`ProviderFactory` in `shared/core` and registering it with `ProviderCatalog`. No
|
||||
UI or platform code needs to change — the settings screen builds its connection
|
||||
fields from what the provider declares.
|
||||
|
||||
## Licence
|
||||
|
||||
MIT.
|
||||
Reference in New Issue
Block a user