Files
t5de-api/docs/pack.md
T
dhkatzandClaude Opus 5.5 9bdc3ff455 Add pack, cfl and safehtml
pack loads local product packs (format 1): t5de-product.json and the product's files, as product.chkn or
files/, with index.xml's rating, type, gender and parent product. cfl writes and reads IMVU's product
container, uncompressed. safehtml cleans product descriptions by an allowlist (bluemonday).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-29 02:52:59 -07:00

87 lines
3.6 KiB
Markdown

# Product packs (format 1)
A product pack is a folder on the user's machine holding one community product: its manifest,
`t5de-product.json`, and the product's files. T5DE's proxy serves packs to the client as if they were IMVU
products. Package `pack` reads and checks them (`pack.Load`).
```
blue-fur-coat/
t5de-product.json
product.chkn the files, zipped (or files/, not both)
```
## Manifest
`t5de-product.json`, UTF-8 JSON:
```json
{
"format": 1,
"id": "blue-fur-coat",
"revision": 1,
"name": "Blue Fur Coat",
"creator": "Some Creator",
"description": "<p>HTML description</p>",
"rating": "general"
}
```
| Field | Rules |
| --- | --- |
| `format` | 1 |
| `id` | 1-64 of `a-z`, `0-9` and `-`, not starting or ending with `-`. Names the product locally; the hub assigns global IDs later. |
| `revision` | an integer, at least 1. Raise it when the files change, so the client doesn't keep the old ones cached. |
| `name` | 1-64 characters after trimming spaces, no control characters |
| `creator` | optional; up to 64 characters, no control characters |
| `description` | optional; HTML, up to 20000 bytes. Cleaned by an allowlist (package `safehtml`) wherever it's shown. |
| `rating` | `general` or `adult`; must agree with `index.xml` (below) |
Other fields are an error, and so is anything after the object.
## Files
The product's files are IMVU's product files, as Create Mode makes them: `index.xml` (required), meshes
(`.xmf`), materials (`.xrf`), textures (`.png`, `.jpg`), and so on. They come one of two ways:
- `product.chkn`: a zip file, Create Mode's project format, with the files at its root. Folder entries are
ignored; files inside folders are an error.
- `files/`: a folder with the files at its top level. Subfolders are an error.
Having both is an error. Other files in the pack's folder are ignored.
Rules for each file:
- Names: not empty, no `/` or `\`, not `.` or `..`, no control characters, Latin-1 characters only (CFL files
store names as Latin-1), at most 200 bytes (UTF-8). No two files with the same name.
- `_contents.json` isn't allowed: it makes the client download a product's files separately, which packs don't
support.
- Limits: 512 files, 64 MiB per file, 256 MiB in all (uncompressed; sizes are counted while reading, not taken
from the zip's headers).
`pack.Checksum` hashes the files' names and contents (sha256), so the same files give the same checksum however
they're stored or compressed. The proxy uses it to notice changes.
## index.xml
IMVU's product template (root element `<Template>`). T5DE reads only these top-level elements and ignores the
rest:
| Element | Use |
| --- | --- |
| `ProductRating` | required: `GA` (general) or `AP` (adult), matching the manifest's `rating` |
| `ProductName` | the name Create Mode gave it |
| `ProductGender` | `female`, `male`, ... |
| `ProductTypeID` | optional integer |
| `BodyPatternProductId` | optional integer |
| `__DATAIMPORT` | optional: `product://<id>/index.xml`, the IMVU product it derives from |
A product derives from an IMVU parent product, as every IMVU product does: the client loads the parent's files
first (from IMVU, as usual) and the pack's files on top. So a pack holds only what it changes, and the parent's
files never pass through T5DE.
## How the proxy serves a pack
The proxy builds the files into a CFL, IMVU's product container (package `cfl`), uncompressed, files in name
order, and serves it where the client asks for the product's files. The revision is part of the address the
client caches the product under, so a new revision makes clients load the new files.