Manifest format - sapientes/unsup GitHub Wiki
unsup pack format
An unsup pack is made up of two distinct parts; manifests and blobs.
Manifests describe metadata about the pack, such as its name, what versions are available, what files are in which versions, etc. Blobs are the files that are downloaded into the working directory as part of an update or bootstrap. They are stored in a specific directory based on the hash of the file's contents — which hash algorithm is used is customizable.
Manifests are all JSON.
Base Manifest Format
Every unsup manifest must contain a unsup_manifest key describing what kind
of manifest it is, to ensure the correct file has been downloaded and that it's
not some other kind of JSON file.
The value of this key must be a string, in format type-version, where type
can be any of the following, and version is an integer:
- root
- bootstrap
- update
Currently, the version must always be 1 or the manifest is rejected.
Root Manifest Format
The root manifest is the entry point to an unsup pack, generally located at
$PACK_ROOT/manifest.json. (The root manifest is the only manifest file that
doesn't require a specific name.)
The name and versions keys are required. What follows is an example manifest
with every possible thing defined:
{
"unsup_manifest": "root-1",
"name": "Una's Sweet Test Modpack",
"versions": {
"current": { "name": "1.1.0", "code": 3 },
"history": [
{ "name": "1.0.1", "code": 2 },
{ "name": "1.0.0", "code": 1 }
]
},
"component_versions": {
"unsup": "0.3.0",
"minecraft": "1.16.5",
"fabric": "0.14.22"
},
"flavor_groups": [
{
"id": "rendering_mod",
"name": "Rendering Mod",
"description": "Which rendering mod you'd like to use.\nIncreases or decreases performance depending on choices.",
"envs": [ "client" ],
"choices": [
{
"id": "no_rendering_mods",
"name": "None",
"description": "No rendering mods."
},
{
"id": "sodium",
"name": "Sodium",
"description": "Installs Sodium and Indium, greatly increasing performance."
},
{
"id": "iris",
"name": "Iris",
"description": "Installs Sodium, Indium, and Iris, increasing performance and providing support for OptiFine shaderpacks."
},
{
"id": "canvas",
"name": "Canvas",
"description": "Installs Canvas, providing support for Canvas shaderpacks."
}
]
},
{
"id": "hard_mode",
"name": "Hard Mode",
"choices": ["hard_mode_off", "hard_mode_on"]
}
]
}
name is a freeform string that gives the human-readable name of the pack. It
is presented to users.
versions is an object that must define current and may define history.
current is a Version object (described below) describing the most up to date
version of the pack. history is an array of past versions in reverse
chronological order.
A version object must define two keys; name and code. name is the
human-readable string name of this version, and code is the machine-readable
number of this version. Version codes must be monotonic (i.e. newer versions
must have higher version codes than older ones).
flavors defines user-selectable alternative configurations, presented when the
pack is first installed. A flavor must define a machine-readable id, a
human-readable name, and optionally an array of environments that the flavor
is applicable for. (Environments are described in more detail in Config format).
All flavors are mutually exclusive. This key is deprecated as of 0.2.0 -
usage of flavor_groups is encouraged.
flavor_groups works as above, but allows specifying groups of flavors,
instead of all flavors being mutually exclusive. This key is new in 0.2.0.
Choice IDs must be unique between all flavor groups. A flavor group must
define a machine-readable id, a human-readable name, optionally an array
of environments that the group is applicable for, optionally a human-readable
description, and an array of choices containing individual flavors thereof.
Each flavor must have an id, and optionally a name or description. If
a flavor group has exactly two choices that end in _off and _on, then it
will be presented as a checkbox and the name is irrelevant. For this, you can
use a string as shorthand to specify only the ID.
component_versions is new in 0.3.0, and describes the versions of the various
"components" of this pack. It may be used by installers or generators to create
appropriate instances, and can be used by unsup to update an mmc-pack.json
in the parent directory if update_mmc_pack is enabled in the unsup.ini, which
it is in the minecraft preset.
The unsup creator will additionally put a special creator object in the root
manifest containing additional information. This information is specific to the
creator and is for the pack maintainer's convenience, and no format for this
object is specified or guaranteed.
Version Manifest Format
Version manifests must be located in a folder that is a sibling of the manifest,
called versions, with their filename being CODE.json, where CODE is the
numeric code of this version.
For example, if the manifest is at foo/bar/manifest.json, then the version
manifest for version code 1 must be located at foo/bar/versions/1.json.
A version manifest describes the difference between the previous version and this version (or, in the case of the first version manifest, the initial state of the pack).
What follows is a minimal example of a version manifest:
{
"hash_function": "SHA-2 256",
"changes": [
{
"path": "mods/fabrication-1.16-1.3.5-aloe6.jar",
"from_size": 0,
"from_hash": null,
"to_hash": "1ab96ff0759b379f65175257e31bfc4fce28a94298591ec7a2a78d41ea6e7253",
"to_size": 1034736
}
],
"unsup_manifest": "update-1"
}
hash_function can be any supported hash function, which are at this time:
MD5(deprecated)SHA-1(deprecated)SHA-2 256(recommended)SHA-2 384SHA-2 512SHA-2 512/256
Using a deprecated hash function will cause the agent to print a warning while updating. Hashes are used to uniquely identify files to be updated.
changes is an array of change objects describing what has changed in this
version. path is the path within the working directory that the file will
be written to. from_size is the size of the old file, from_hash is the hash
of the old file, to_size is the size of the new file, and to_hash is the
hash of the new file.
If from_hash or to_hash are omitted, they are assumed to be null. A
deleted file is represented with a size of 0 and a hash of null.
Files will be downloaded from the path $PACK_ROOT/blobs/AA/AABBCCCC, for
a hash of AABBCCCC. This can be overridden by specifying url, which will
change where the file is downloaded from. In both cases, the hash and size of
the file will be verified after downloading, and if they do not match updating
will be aborted with an error. This can be used to avoid running afoul of the
terms of mods with restricted redistribution by downloading them direct from
their official source, such as CurseForge.
envs may also be specified, which is an array of strings defining the
environments in which this file is relevant. For example, this can be set to
[ "client" ] for a client-only mod to prevent it from being downloaded to a
server. If not specified, it is assumed the file is relevant for all
environments.
flavors may be similarly specified to limit the file to a specific flavor.
An HTML changelog may be specified for a version by placing a CODE.html
alongside the CODE.json file. This will be displayed to the user in a Swing
HTML pane when they're being asked if they would like to install the update.
Bootstrap Manifest Format
The bootstrap manifest is a shortcut for new installs, to avoid having to
download and resolve every version manifest. (In such a case, the agent will
fully resolve the state before downloading any blobs, but it is still needlessly
inefficient.) It must be located at $PACK_ROOT/bootstrap.json.
The bootstrap manifest is completely optional.
{
"unsup_manifest": "bootstrap-1",
"version": { "name": "1.1.0", "code": 3 },
"hash_function": "SHA-2 256",
"files": [
{
"path": "icon.png",
"hash": "15fff92e3c62cc3ca41121b29e13f6110a75e631ae3983e9bf577208518dd831",
"size": 6411
}
]
}
version is a Version object defining the version that this bootstrap manifest
describes. If this does not match the latest version, the agent will come up to
speed by downloading any manifests between the bootstrap and current. This
allows only updating the bootstrap periodically, instead of needing to manage
it for every update, which is useful when writing manifests by hand.
hash_function is the same as defined in the Update Manifest Format.
files is an array of files, which work identically to changes in an Update
Manifest, but from_hash and from_size are omitted and implied to be null/0, and
hash and size become to_hash and to_size. url, envs, and flavors
may be specified in a file just like a change.