webstation-broker
DeveloperPython reference

memcard

Whole memory-card sync: an emulator's Slot-1 card as one owned image.

Whole memory-card sync: an emulator's Slot-1 card as one owned image.

Distinct from the archive path in saves.py, which ships only what a session changed. A card travels whole, so a user's card can be laid down on any pooled container and the previous player's saves never survive into the next session. The card is a directory (a folder card), which is what makes it zippable and replaceable as an image; a single-file card is refused rather than mangled.

attributelog
= logging.getLogger(__name__)
attributeLOCK
= Lock()

Serializes whole-card operations.

Staging and backup paths are derived from the card name alone, so two concurrent replaces would rmtree each other mid-write.

func_card_files(card) -> list[Path]

List every regular file in the card directory, sorted, skipping symlinks.

paramcardPath

The folder card's directory.

Returns

list

The files found, in sorted order.

func_is_blank_marker(path, card, marker) -> bool

Whether path is the marker file while it is still the empty one we laid down.

parampathPath

A file inside the card.

paramcardPath

The folder card's directory.

parammarkerOptional[str]

The marker filename the emulator expects, or None when it has none.

Returns

bool

True only for the marker file while it is still zero bytes.

funcensure_card(card, marker) -> None

Have a card the emulator will actually open waiting at card.

A bare directory is not enough. PCSX2 skips any directory in its memcards folder that carries no marker file, so the slot reads as missing and the game has nowhere to save. The marker goes down empty, which is exactly what PCSX2 writes when it creates a folder card, and stays empty until the card is formatted.

paramcardPath

The folder card's directory, created if missing.

parammarkerOptional[str]

The marker filename to touch inside it, or None to skip the marker.

Returns

None
funcbuild_archive(card, marker=None) -> Optional[Union[bytes, str]]

Zip the whole card at card, members relative to the card root.

Relative so the image carries no trace of the card's name and can be laid down on a container that calls its card something else. A card holding nothing but the blank marker counts as no card at all.

paramcardPath

The folder card's directory.

parammarkerOptional[str]
= None

The marker filename the emulator expects, or None when it has none.

Returns

typing.Optional

The zip bytes, None when the slot holds no card, or an error string when

funcreplace(card, content, marker=None) -> Union[int, str]

Wipe the card at card and lay the pulled image down in its place.

The whole card is replaced with no per-file merge: that is what isolates the next player on a pooled container from the last one. Extraction goes to a staging directory that is swapped over the live card, so a failure part way through never leaves a half-wiped card.

paramcardPath

The folder card's directory to replace.

paramcontentbytes

The zip image of the card, members relative to the card root.

parammarkerOptional[str]
= None

The marker filename to lay down before the members, or None to skip it.

Returns

typing.Union

The number of files written, or an error string when the slot holds a