Add drafts of JSON schemas

This commit is contained in:
Exter-N 2025-01-17 01:45:37 +01:00
parent df148b556a
commit a1931a93fb
4 changed files with 768 additions and 0 deletions

486
schemas/container.json Normal file
View file

@ -0,0 +1,486 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://raw.githubusercontent.com/xivdev/Penumbra/master/schemas/container.json",
"type": "object",
"properties": {
"Name": {
"description": "Name of the container/option/sub-mod.",
"type": ["string", "null"]
},
"Files": {
"description": "File redirections in this container. Keys are game paths, values are relative file paths.",
"type": "object",
"patternProperties": {
"^[^/\\\\][^\\\\]*$": {
"type": "string",
"pattern": "^[^/\\\\][^/]*$"
}
},
"additionalProperties": false
},
"FileSwaps": {
"description": "File swaps in this container. Keys are original game paths, values are actual game paths.",
"type": "object",
"patternProperties": {
"^[^/\\\\][^\\\\]*$": {
"type": "string",
"pattern": "^[^/\\\\][^/]*$"
}
},
"additionalProperties": false
},
"Manipulations": {
"type": "array",
"items": {
"$ref": "#/$defs/Manipulation"
}
}
},
"$defs": {
"Manipulation": {
"type": "object",
"properties": {
"Type": {
"enum": ["Unknown", "Imc", "Eqdp", "Eqp", "Est", "Gmp", "Rsp", "GlobalEqp", "Atch"]
},
"Manipulation": {
"type": ["object", "null"]
}
},
"required": ["Type", "Manipulation"],
"oneOf": [
{
"properties": {
"Type": {
"const": "Unknown"
},
"Manipulation": {
"type": "null"
}
}
}, {
"properties": {
"Type": {
"const": "Imc"
},
"Manipulation": {
"$ref": "#/$defs/ImcManipulation"
}
}
}, {
"properties": {
"Type": {
"const": "Eqdp"
},
"Manipulation": {
"$ref": "#/$defs/EqdpManipulation"
}
}
}, {
"properties": {
"Type": {
"const": "Eqp"
},
"Manipulation": {
"$ref": "#/$defs/EqpManipulation"
}
}
}, {
"properties": {
"Type": {
"const": "Est"
},
"Manipulation": {
"$ref": "#/$defs/EstManipulation"
}
}
}, {
"properties": {
"Type": {
"const": "Gmp"
},
"Manipulation": {
"$ref": "#/$defs/GmpManipulation"
}
}
}, {
"properties": {
"Type": {
"const": "Rsp"
},
"Manipulation": {
"$ref": "#/$defs/RspManipulation"
}
}
}, {
"properties": {
"Type": {
"const": "GlobalEqp"
},
"Manipulation": {
"$ref": "#/$defs/GlobalEqpManipulation"
}
}
}, {
"properties": {
"Type": {
"const": "Atch"
},
"Manipulation": {
"$ref": "#/$defs/AtchManipulation"
}
}
}
],
"additionalProperties": false
},
"ImcManipulation": {
"type": "object",
"properties": {
"Entry": {
"$ref": "#/$defs/ImcEntry"
},
"Valid": {
"type": "boolean"
}
},
"required": [
"Entry"
],
"allOf": [
{
"$ref": "#/$defs/ImcIdentifier"
}
],
"unevaluatedProperties": false
},
"ImcIdentifier": {
"type": "object",
"properties": {
"PrimaryId": {
"type": "integer"
},
"SecondaryId": {
"type": "integer"
},
"Variant": {
"type": "integer"
},
"ObjectType": {
"$ref": "#/$defs/ObjectType"
},
"EquipSlot": {
"$ref": "#/$defs/EquipSlot"
},
"BodySlot": {
"$ref": "#/$defs/BodySlot"
}
},
"required": [
"PrimaryId",
"SecondaryId",
"Variant",
"ObjectType",
"EquipSlot",
"BodySlot"
]
},
"ImcEntry": {
"type": "object",
"properties": {
"AttributeAndSound": {
"type": "integer"
},
"MaterialId": {
"type": "integer"
},
"DecalId": {
"type": "integer"
},
"VfxId": {
"type": "integer"
},
"MaterialAnimationId": {
"type": "integer"
},
"AttributeMask": {
"type": "integer"
},
"SoundId": {
"type": "integer"
}
},
"required": [
"MaterialId",
"DecalId",
"VfxId",
"MaterialAnimationId",
"AttributeMask",
"SoundId"
],
"additionalProperties": false
},
"EqdpManipulation": {
"type": "object",
"properties": {
"Entry": {
"type": "integer"
},
"Gender": {
"$ref": "#/$defs/Gender"
},
"Race": {
"$ref": "#/$defs/ModelRace"
},
"SetId": {
"$ref": "#/$defs/LaxInteger"
},
"Slot": {
"$ref": "#/$defs/EquipSlot"
},
"ShiftedEntry": {
"type": "integer"
}
},
"required": [
"Entry",
"Gender",
"Race",
"SetId",
"Slot"
],
"additionalProperties": false
},
"EqpManipulation": {
"type": "object",
"properties": {
"Entry": {
"type": "integer"
},
"SetId": {
"$ref": "#/$defs/LaxInteger"
},
"Slot": {
"$ref": "#/$defs/EquipSlot"
}
},
"required": [
"Entry",
"SetId",
"Slot"
],
"additionalProperties": false
},
"EstManipulation": {
"type": "object",
"properties": {
"Entry": {
"type": "integer"
},
"Gender": {
"$ref": "#/$defs/Gender"
},
"Race": {
"$ref": "#/$defs/ModelRace"
},
"SetId": {
"$ref": "#/$defs/LaxInteger"
},
"Slot": {
"enum": ["Hair", "Face", "Body", "Head"]
}
},
"required": [
"Entry",
"Gender",
"Race",
"SetId",
"Slot"
],
"additionalProperties": false
},
"GmpManipulation": {
"type": "object",
"properties": {
"Entry": {
"type": "object",
"properties": {
"Enabled": {
"type": "boolean"
},
"Animated": {
"type": "boolean"
},
"RotationA": {
"type": "number"
},
"RotationB": {
"type": "number"
},
"RotationC": {
"type": "number"
},
"UnknownA": {
"type": "number"
},
"UnknownB": {
"type": "number"
},
"UnknownTotal": {
"type": "number"
},
"Value": {
"type": "number"
}
},
"required": [
"Enabled",
"Animated",
"RotationA",
"RotationB",
"RotationC",
"UnknownA",
"UnknownB",
"UnknownTotal",
"Value"
],
"additionalProperties": false
},
"SetId": {
"$ref": "#/$defs/LaxInteger"
}
},
"required": [
"Entry",
"SetId"
],
"additionalProperties": false
},
"RspManipulation": {
"type": "object",
"properties": {
"Entry": {
"type": "number"
},
"SubRace": {
"$ref": "#/$defs/SubRace"
},
"Attribute": {
"$ref": "#/$defs/RspAttribute"
}
},
"additionalProperties": false
},
"GlobalEqpManipulation": {
"type": "object",
"properties": {
"Condition": {
"type": "integer"
},
"Type": {
"enum": ["DoNotHideEarrings", "DoNotHideNecklace", "DoNotHideBracelets", "DoNotHideRingR", "DoNotHideRingL", "DoNotHideHrothgarHats", "DoNotHideVieraHats"]
}
},
"additionalProperties": false
},
"AtchManipulation": {
"type": "object",
"properties": {
"Entry": {
"type": "object",
"properties": {
"Bone": {
"type": "string",
"maxLength": 34
},
"Scale": {
"type": "number"
},
"OffsetX": {
"type": "number"
},
"OffsetY": {
"type": "number"
},
"OffsetZ": {
"type": "number"
},
"RotationX": {
"type": "number"
},
"RotationY": {
"type": "number"
},
"RotationZ": {
"type": "number"
}
},
"required": [
"Bone",
"Scale",
"OffsetX",
"OffsetY",
"OffsetZ",
"RotationX",
"RotationY",
"RotationZ"
],
"additionalProperties": false
},
"Gender": {
"$ref": "#/$defs/Gender"
},
"Race": {
"$ref": "#/$defs/ModelRace"
},
"Type": {
"type": "string",
"minLength": 3,
"maxLength": 3
},
"Index": {
"type": "integer"
}
},
"required": [
"Entry",
"Gender",
"Race",
"Type",
"Index"
],
"additionalProperties": false
},
"LaxInteger": {
"oneOf": [
{
"type": "integer"
}, {
"type": "string",
"pattern": "^\\d+$"
}
]
},
"EquipSlot": {
"enum": ["Unknown", "MainHand", "OffHand", "Head", "Body", "Hands", "Belt", "Legs", "Feet", "Ears", "Neck", "Wrists", "RFinger", "BothHand", "LFinger", "HeadBody", "BodyHandsLegsFeet", "SoulCrystal", "LegsFeet", "FullBody", "BodyHands", "BodyLegsFeet", "ChestHands", "Nothing", "All"]
},
"Gender": {
"enum": ["Unknown", "Male", "Female", "MaleNpc", "FemaleNpc"]
},
"ModelRace": {
"enum": ["Unknown", "Midlander", "Highlander", "Elezen", "Lalafell", "Miqote", "Roegadyn", "AuRa", "Hrothgar", "Viera"]
},
"ObjectType": {
"enum": ["Unknown", "Vfx", "DemiHuman", "Accessory", "World", "Housing", "Monster", "Icon", "LoadingScreen", "Map", "Interface", "Equipment", "Character", "Weapon", "Font"]
},
"BodySlot": {
"enum": ["Unknown", "Hair", "Face", "Tail", "Body", "Zear"]
},
"SubRace": {
"enum": ["Unknown", "Midlander", "Highlander", "Wildwood", "Duskwight", "Plainsfolk", "Dunesfolk", "SeekerOfTheSun", "KeeperOfTheMoon", "Seawolf", "Hellsguard", "Raen", "Xaela", "Helion", "Lost", "Rava", "Veena"]
},
"RspAttribute": {
"enum": ["MaleMinSize", "MaleMaxSize", "MaleMinTail", "MaleMaxTail", "FemaleMinSize", "FemaleMaxSize", "FemaleMinTail", "FemaleMaxTail", "BustMinX", "BustMinY", "BustMinZ", "BustMaxX", "BustMaxY", "BustMaxZ"]
}
}
}

25
schemas/default_mod.json Normal file
View file

@ -0,0 +1,25 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://raw.githubusercontent.com/xivdev/Penumbra/master/schemas/container.json",
"allOf": [
{
"type": "object",
"properties": {
"Version": {
"description": "???",
"type": ["integer", "null"]
},
"Description": {
"description": "Description of the sub-mod.",
"type": ["string", "null"]
},
"Image": {
"description": "Unused by Penumbra.",
"type": ["string", "null"]
}
}
}, {
"$ref": "https://raw.githubusercontent.com/xivdev/Penumbra/master/schemas/container.json"
}
]
}

206
schemas/group.json Normal file
View file

@ -0,0 +1,206 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://raw.githubusercontent.com/xivdev/Penumbra/master/schemas/group.json",
"type": "object",
"properties": {
"Version": {
"description": "???",
"type": ["integer", "null"]
},
"Name": {
"description": "Name of the group.",
"type": "string"
},
"Description": {
"description": "Description of the group.",
"type": ["string", "null"]
},
"Image": {
"description": "Relative path to a preview image for the group. Unused by Penumbra, present for round-trip import/export of TexTools-generated mods.",
"type": ["string", "null"]
},
"Page": {
"description": "TexTools page of the group. Unused by Penumbra, present for round-trip import/export of TexTools-generated mods.",
"type": ["integer", "null"]
},
"Priority": {
"description": "Priority of the group. If several groups define conflicting files or manipulations, the highest priority wins.",
"type": ["integer", "null"]
},
"Type": {
"description": "Group type. Single groups have one and only one of their options active at any point. Multi groups can have zero, one or many of their options active. Combining groups have n options, 2^n containers, and will have one and only one container active depending on the selected options.",
"enum": ["Single", "Multi", "Imc", "Combining"]
},
"DefaultSettings": {
"description": "Default configuration for the group.",
"type": "integer"
}
},
"required": [
"Name",
"Type"
],
"oneOf": [
{
"properties": {
"Type": {
"const": "Single"
},
"Options": {
"type": "array",
"items": {
"allOf": [
{
"type": "object",
"properties": {
"Description": {
"description": "Description of the option.",
"type": ["string", "null"]
},
"Image": {
"description": "Unused by Penumbra.",
"type": ["string", "null"]
}
}
}, {
"$ref": "https://raw.githubusercontent.com/xivdev/Penumbra/master/schemas/container.json"
}
]
}
}
}
}, {
"properties": {
"Type": {
"const": "Multi"
},
"Options": {
"type": "array",
"items": {
"allOf": [
{
"type": "object",
"properties": {
"Description": {
"description": "Description of the option.",
"type": ["string", "null"]
},
"Priority": {
"description": "Priority of the option. If several enabled options within the group define conflicting files or manipulations, the highest priority wins.",
"type": ["integer", "null"]
},
"Image": {
"description": "Unused by Penumbra.",
"type": ["string", "null"]
}
}
}, {
"$ref": "https://raw.githubusercontent.com/xivdev/Penumbra/master/schemas/container.json"
}
]
}
}
}
}, {
"properties": {
"Type": {
"const": "Imc"
},
"AllVariants": {
"type": "boolean"
},
"OnlyAttributes": {
"type": "boolean"
},
"Identifier": {
"$ref": "https://raw.githubusercontent.com/xivdev/Penumbra/master/schemas/container.json#/$defs/ImcIdentifier"
},
"DefaultEntry": {
"$ref": "https://raw.githubusercontent.com/xivdev/Penumbra/master/schemas/container.json#/$defs/ImcEntry"
},
"Options": {
"type": "array",
"items": {
"type": "object",
"properties": {
"Name": {
"description": "Name of the option.",
"type": "string"
},
"Description": {
"description": "Description of the option.",
"type": ["string", "null"]
},
"Image": {
"description": "Unused by Penumbra.",
"type": ["string", "null"]
}
},
"required": [
"Name"
],
"oneOf": [
{
"properties": {
"AttributeMask": {
"type": "integer"
}
},
"required": [
"AttributeMask"
]
}, {
"properties": {
"IsDisableSubMod": {
"const": true
}
},
"required": [
"IsDisableSubMod"
]
}
],
"unevaluatedProperties": false
}
}
}
}, {
"properties": {
"Type": {
"const": "Combining"
},
"Options": {
"type": "array",
"items": {
"type": "object",
"properties": {
"Name": {
"description": "Name of the option.",
"type": "string"
},
"Description": {
"description": "Description of the option.",
"type": ["string", "null"]
},
"Image": {
"description": "Unused by Penumbra.",
"type": ["string", "null"]
}
},
"required": [
"Name"
],
"additionalProperties": false
}
},
"Containers": {
"type": "array",
"items": {
"$ref": "https://raw.githubusercontent.com/xivdev/Penumbra/master/schemas/container.json"
}
}
}
}
],
"unevaluatedProperties": false
}

51
schemas/meta-v3.json Normal file
View file

@ -0,0 +1,51 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://raw.githubusercontent.com/xivdev/Penumbra/master/schemas/meta-v3.json",
"title": "Penumbra Mod Metadata",
"description": "Metadata of a Penumbra mod.",
"type": "object",
"properties": {
"FileVersion": {
"description": "Major version of the metadata schema used.",
"type": "integer",
"minimum": 3,
"maximum": 3
},
"Name": {
"description": "Name of the mod.",
"type": "string"
},
"Author": {
"description": "Author of the mod.",
"type": ["string", "null"]
},
"Description": {
"description": "Description of the mod. Can span multiple paragraphs.",
"type": ["string", "null"]
},
"Image": {
"description": "Relative path to a preview image for the mod. Unused by Penumbra, present for round-trip import/export of TexTools-generated mods.",
"type": ["string", "null"]
},
"Version": {
"description": "Version of the mod. Can be an arbitrary string.",
"type": ["string", "null"]
},
"Website": {
"description": "URL of the web page of the mod.",
"type": ["string", "null"]
},
"ModTags": {
"description": "Author-defined tags for the mod.",
"type": "array",
"items": {
"type": "string"
},
"uniqueItems": true
}
},
"required": [
"FileVersion",
"Name"
]
}