Documentation
¶
Overview ¶
Package smapi reads SMAPI mod manifests and orders mods the way SMAPI's mod resolver does.
Parse reads a manifest.json as leniently as SMAPI's Json.NET reader. Resolve returns mods in SMAPI's load order. Mod ids (UniqueID) are case-insensitive and compared with FoldID.
Index ¶
- Constants
- Variables
- func CurseForgeUpdateKey(key string) (string, bool)
- func FoldID(uniqueID string) string
- func GitHubUpdateKey(key string) (string, bool)
- func NexusUpdateKey(key string) (int, bool)
- func RewriteDependencies(raw []byte, want, drop []string) ([]byte, error)
- type Dependency
- type Manifest
- type Mod
- type Row
- type Status
Constants ¶
const FileName = "manifest.json"
FileName is the manifest file SMAPI looks for.
const MaxManifestSize = 4 << 20
MaxManifestSize is the largest manifest Parse reads. Real manifests are a few kilobytes; the bound keeps a crafted file from costing memory in proportion to its size.
Variables ¶
var ErrTooLarge = errors.New("manifest is too large")
ErrTooLarge is returned by Parse for input over MaxManifestSize.
Functions ¶
func CurseForgeUpdateKey ¶
CurseForgeUpdateKey returns the project id of a "CurseForge:<id>" update key; the id is a positive number.
func FoldID ¶
FoldID is the key a UniqueID is compared by: SMAPI ids are case-insensitive and may carry stray spaces.
func GitHubUpdateKey ¶
GitHubUpdateKey returns the "owner/repo" of a "GitHub:owner/repo" update key. A repo that would move the path of a URL built from it ("..", "o/r?x", "o/r/s") is refused.
func NexusUpdateKey ¶
NexusUpdateKey returns the mod page of a "Nexus:1234" or "Nexus:1234@subkey" update key.
func RewriteDependencies ¶
RewriteDependencies returns manifest.json text with each UniqueID in want added as an optional dependency (unless it is already listed) and each optional dependency in drop that is not in want removed. Other keys, in any casing, are kept; the output is strict JSON, so comments in the input are lost.
Types ¶
type Dependency ¶
type Dependency struct {
UniqueID string
// MinimumVersion is the oldest version of the dependency that works; empty for any.
MinimumVersion string
// IsRequired is true when the manifest omits IsRequired, as in SMAPI.
IsRequired bool
}
Dependency is one mod another mod needs.
func (Dependency) Check ¶ added in v0.2.0
func (d Dependency) Check(installed string) Status
Check compares an installed version of the dependency with MinimumVersion. It is Unknown when either version does not parse; an empty MinimumVersion is Met whatever is installed.
func (Dependency) SatisfiedBy ¶
func (d Dependency) SatisfiedBy(installed string) bool
SatisfiedBy reports whether an installed version of the dependency meets MinimumVersion. It is false only when both versions parse and the installed one is older, so an unreadable version never blocks a mod.
type Manifest ¶
type Manifest struct {
Name string
Author string
Version string
UniqueID string
Description string
UpdateKeys []string
// EntryDll is the C# mod's assembly file, relative to the mod folder; empty for content packs.
EntryDll string
// ContentPackFor is the framework's UniqueID when the manifest declares a ContentPackFor.
ContentPackFor string
// Dependencies lists Dependencies[] and, as a required entry, the ContentPackFor framework.
Dependencies []Dependency
// UpdateCautionMessage is the author's warning to show before updating to this version.
UpdateCautionMessage string
// MinimumGameVersion is the oldest game version the mod runs on, when it declares one.
MinimumGameVersion string
// MinimumAPIVersion is the oldest SMAPI the mod runs on, as written; empty when it declares none.
MinimumAPIVersion string
// DeleteOldVersion asks an updater to remove the previous version's files rather than overlay them.
DeleteOldVersion bool
}
Manifest holds the manifest.json fields a mod manager reads.
func Parse ¶
Parse reads a manifest tolerating a BOM or UTF-16/32 text, comments, trailing commas, single quotes, unquoted names, curly quotes and any key casing. A manifest without a UniqueID is an error, since nothing can refer to that mod. Input over MaxManifestSize is ErrTooLarge.
func (Manifest) CheckSMAPI ¶ added in v0.2.0
CheckSMAPI compares the installed SMAPI version with MinimumAPIVersion, which SMAPI refuses to load a mod below. It is Unknown when either version does not parse; no MinimumAPIVersion is Met.
type Mod ¶
type Mod struct {
UniqueID string
Name string
// Folder is the mod's folder; its name orders the walk, as SMAPI's scanner meets folders. Either OS separator is read.
Folder string
// Dependencies are in the order the manifest declares them. MinimumVersion is not read.
Dependencies []Dependency
ContentPackFor string
}
Mod is the manifest fields the resolver needs.
type Row ¶
type Row struct {
// Position counts from 1.
Position int
UniqueID string
Name string
// Required and Optional are the UniqueIDs the mod depends on, as declared.
Required []string
Optional []string
// Dependents are the loaded mods that depend on this one, in folder order.
Dependents []string
// MissingRequired are required dependencies no listed mod provides.
MissingRequired []string
// Cycle is set on a mod that a dependency loop stopped, and on those depending on it.
Cycle bool
}
Row is one mod in load order.
func Resolve ¶
Resolve returns mods in SMAPI's load order, which is ModResolver.ProcessDependencies (Pathoschild/SMAPI develop e5b8bf3, src/SMAPI/Framework/ModLoading/ModResolver.cs:221-391): it walks the mods in folder order and loads each mod's dependencies (required, optional, and the mod a content pack is for) just before it, depth first. Duplicate UniqueIDs keep the first. A mod that misses a required dependency, or that a dependency loop or a failed required dependency stops, is placed where SMAPI gives up on it. The walk visits each mod once, so a loop ends at the first mod that meets itself.