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]>
87 lines
3.6 KiB
Markdown
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.
|