From 14d21ad6a37d4173377c54bc6a32d009d84b6fcc Mon Sep 17 00:00:00 2001 From: pleb Date: Sun, 19 Apr 2026 09:09:17 -0700 Subject: [PATCH] Add a readme file --- README.md | 104 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..0ec5c7d --- /dev/null +++ b/README.md @@ -0,0 +1,104 @@ +# Setlist + +A small Beat Saber (PC, BSIPA) plugin that syncs in-game playlist edits back to +[BeatLeader](https://beatleader.com) so your playlists stay current outside the +game — on the website, on your phone, or shared with friends. + +## What it does + +When you add a map to a playlist in-game (via the standard +[PlaylistManager](https://github.com/rithik-b/PlaylistManager) "Add to playlist" +flow), Setlist: + +1. Watches `PlaylistManager.Utilities.Events.playlistSongAdded`. +2. Checks whether the playlist is a **BeatLeader-synced playlist owned by you** + — i.e. its `customData.syncURL` is an `api.beatleader.com/playlist/guid/…` + URL and its `customData.owner` matches your platform user id. +3. Serializes the updated playlist and **POSTs it back to BeatLeader** + (`POST /user/playlist?id=…&shared=…`). + +The POST reuses the [BeatLeader mod](https://github.com/BeatLeader/beatleader-mod)'s +authenticated session — no extra login, no API token in your config, nothing to +copy/paste. If BeatLeader is signed in, Setlist is signed in. + +The result: edit playlists in VR; see them updated on the website and any +device that consumes them, without alt-tabbing or running a sync script. + +## Requirements + +- Beat Saber `1.40.8` (PC), via BSIPA. +- [BeatLeader](https://github.com/BeatLeader/beatleader-mod) `^0.9.0` — must be + installed **and signed in** for the sync to authenticate. +- [PlaylistManager](https://github.com/rithik-b/PlaylistManager) `^1.7.0`. +- [BeatSaberPlaylistsLib](https://github.com/Zingabopp/BeatSaberPlaylistsLib) + `^1.7.0` (transitive via PlaylistManager). + +See `Setlist/manifest.json` for the authoritative list. + +## Install + +Drop `Setlist.dll` into `Beat Saber/Plugins/` alongside BeatLeader and +PlaylistManager (BSManager works fine). Confirm in `Logs/_latest.log`: + +``` +[INFO @ ...] [Setlist|...] platformUserId=... +[INFO @ ...] [Setlist|...] Playlist "...": hasSyncUrl=True, owner=..., ownerMatchesPlatform=true (...) +``` + +When you add a map to one of those playlists in-game you should then see: + +``` +[INFO @ ...] [Setlist|...] Setlist BeatLeader sync: OK HTTP 200 playlist="..." body=... +``` + +## Build (Linux / NixOS, no Visual Studio / Rider) + +This whole plugin is built from the `dotnet` CLI on Linux — including NixOS — +no BSMT IDE extension required. The Linux + Cursor toolchain (.NET SDK 9, BSMT +MSBuild tasks, the missing-`net472`-reference-assemblies workaround, and the +"copy DLL into `Plugins/` on a Unix host" target) is documented in: + +- [`docs/pc-modding.md`](docs/pc-modding.md) — full guide, adapted from the BSMG + wiki for Linux + Cursor + LLM-assisted dev. +- [`docs/bootstrap.md`](docs/bootstrap.md) — exactly how this project was + scaffolded (template, NuGet pins, `BeatSaberDir`, etc.). + +Quick start once `Setlist.csproj.user` points at your install: + +```bash +cd Setlist +dotnet restore +dotnet build -c Debug +``` + +Output: `Setlist/bin/Debug/Setlist.dll`, also copied into +`$BeatSaberDir/Plugins/Setlist.dll` by the Unix-host post-build target. + +## How it integrates with the two host plugins + +Both integrations are deliberately thin and live in a single project so they +can be read end-to-end: + +- **PlaylistManager** — Setlist subscribes to its public + `Events.playlistSongAdded` hook (same one used by the in-game UI flow). + Notes on that flow live in [`docs/playlistmanager-add-map.md`](docs/playlistmanager-add-map.md). + +- **BeatLeader** — Setlist references the shipped `BeatLeader.dll`, waits on + BeatLeader's own `Authentication._signedIn` flag, and POSTs through Unity's + `UnityWebRequest` so the cookies BeatLeader's `HttpClient` already has on the + shared `CookieContainer` are reused. Background and the alternative + "go through `WebRequestFactory` directly" approach are in + [`docs/beatleader-playlist-api.md`](docs/beatleader-playlist-api.md) and + [`docs/beatleader-api-samples.md`](docs/beatleader-api-samples.md). + +## Status + +Early / personal-use. Currently scoped to: + +- Adds (one new song → one POST). Removes, reorders, renames, and bulk edits + are not yet wired. +- BeatLeader as the sync target. The same model would extend to other backends + that accept a full-playlist upload. + +See [`AGENTS.md`](AGENTS.md) for repo conventions (version-bump-on-build, +smoketest, etc.) if you're contributing or letting an agent work in this repo.