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]>
This commit is contained in:
commit
9bdc3ff455
16 files changed
+1638
No files matched your search
@@ -0,0 +1,86 @@
|
||||
# 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.
|
||||
Reference in new issue
Block a user