first commit
This commit is contained in:
68
README.md
Normal file
68
README.md
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
# sortof
|
||||||
|
|
||||||
|
A Project Zomboid mod load-order sorter. Paste Steam Workshop IDs or a
|
||||||
|
collection URL, get back the three lines (`WorkshopItems=`, `Mods=`,
|
||||||
|
`Map=`) you paste into your dedicated server's `.ini` file.
|
||||||
|
|
||||||
|
## Stack
|
||||||
|
|
||||||
|
- **API** — FastAPI + asyncpg, Python 3.12.
|
||||||
|
- **Cache** — PostgreSQL 16. One row per `(workshop_id, mod_id)` parsed
|
||||||
|
from each mod's `mod.info`. Cache invalidates on Steam's
|
||||||
|
`time_updated`; no manual TTLs.
|
||||||
|
- **Drain worker** — pulls cache misses via DepotDownloader, parses
|
||||||
|
`mod.info` and `media/maps/*/map.info`, writes back to Postgres.
|
||||||
|
- **Frontend** — vanilla JSX in `frontend/`, served by FastAPI
|
||||||
|
`StaticFiles`, transpiled in-browser by Babel-standalone. No build
|
||||||
|
step, no npm.
|
||||||
|
- **Deployment** — Docker for Postgres only; the API and drain workers
|
||||||
|
run as systemd units on the host.
|
||||||
|
|
||||||
|
## What it actually does
|
||||||
|
|
||||||
|
- Resolves bare workshop IDs **and** collection URLs (anonymous Steam API
|
||||||
|
expansion).
|
||||||
|
- Topologically sorts mods by `requirements`, `loadAfter`, `loadBefore`
|
||||||
|
with explicit support for `loadFirst` / `loadLast` and the "patch"
|
||||||
|
tier.
|
||||||
|
- Detects multi-branch wsids (e.g. AuthenticZ, Project RV Interior),
|
||||||
|
auto-picks a sensible default by build flavor or input cross-reference,
|
||||||
|
and surfaces the alternates in a picker.
|
||||||
|
- Emits actionable warnings: missing dependencies (with one-click "add"
|
||||||
|
buttons when the dep is in our cache), build-mismatch flags with
|
||||||
|
swap-or-remove actions, duplicate-mod_id conflicts, addon detection,
|
||||||
|
and required-item suggestions scraped from the Workshop page.
|
||||||
|
- Tracks community-reported broken mods per PZ build, with thumbs-up /
|
||||||
|
thumbs-down voting and a search panel.
|
||||||
|
|
||||||
|
## Bootstrapping (rough)
|
||||||
|
|
||||||
|
1. `docker compose up -d sortof_db` — runs Postgres on `127.0.0.1:5439`,
|
||||||
|
applies `init/*.sql` migrations on first boot.
|
||||||
|
2. Create the two virtualenvs:
|
||||||
|
```bash
|
||||||
|
python3.12 -m venv api/.venv && api/.venv/bin/pip install -r api/requirements.txt
|
||||||
|
python3.12 -m venv worker/.venv && worker/.venv/bin/pip install -r worker/requirements.txt
|
||||||
|
```
|
||||||
|
3. Drop a `.env` next to `docker-compose.yml` with `POSTGRES_USER`,
|
||||||
|
`POSTGRES_PASSWORD`, `POSTGRES_DB`, and `SORTOF_CORS_ORIGINS`.
|
||||||
|
4. Set `DD_PATH` to wherever DepotDownloader lives, then start the API
|
||||||
|
(`api/.venv/bin/uvicorn app:app --host 127.0.0.1 --port 8801`) and a
|
||||||
|
drain worker (`worker/.venv/bin/python drain.py`).
|
||||||
|
|
||||||
|
For the systemd units, see `docs/` (and the running host).
|
||||||
|
|
||||||
|
## Layout
|
||||||
|
|
||||||
|
```
|
||||||
|
api/ FastAPI service + adapters + sort engine
|
||||||
|
worker/ drain worker — DepotDownloader + mod.info parser
|
||||||
|
frontend/ vanilla JSX + index.html (no build step)
|
||||||
|
init/ Postgres bootstrap migrations (runs in order)
|
||||||
|
data/ checked-in JSON like pz_versions.json
|
||||||
|
docs/ specs, plans, audit notes
|
||||||
|
```
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
TBD.
|
||||||
Reference in New Issue
Block a user