mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-12 10:17:22 +01:00
Merge branch 'json-schema'
This commit is contained in:
commit
7d75c7d7a5
27 changed files with 1533 additions and 145 deletions
|
|
@ -1 +1 @@
|
|||
Subproject commit 78ce195c171d7bce4ad9df105f1f95cce9bf1150
|
||||
Subproject commit c525072299d5febd2bb638ab229060b0073ba6a6
|
||||
32
Penumbra.sln
32
Penumbra.sln
|
|
@ -24,6 +24,34 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Penumbra.String", "Penumbra
|
|||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Penumbra.CrashHandler", "Penumbra.CrashHandler\Penumbra.CrashHandler.csproj", "{EE834491-A98F-4395-BE0D-6861AE5AD953}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Schemas", "Schemas", "{BFEA7504-1210-4F79-A7FE-BF03B6567E33}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
schemas\default_mod.json = schemas\default_mod.json
|
||||
schemas\group.json = schemas\group.json
|
||||
schemas\local_mod_data-v3.json = schemas\local_mod_data-v3.json
|
||||
schemas\mod_meta-v3.json = schemas\mod_meta-v3.json
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "structs", "structs", "{B03F276A-0572-4F62-AF86-EF62F6B80463}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
schemas\structs\container.json = schemas\structs\container.json
|
||||
schemas\structs\group_combining.json = schemas\structs\group_combining.json
|
||||
schemas\structs\group_imc.json = schemas\structs\group_imc.json
|
||||
schemas\structs\group_multi.json = schemas\structs\group_multi.json
|
||||
schemas\structs\group_single.json = schemas\structs\group_single.json
|
||||
schemas\structs\manipulation.json = schemas\structs\manipulation.json
|
||||
schemas\structs\meta_atch.json = schemas\structs\meta_atch.json
|
||||
schemas\structs\meta_enums.json = schemas\structs\meta_enums.json
|
||||
schemas\structs\meta_eqdp.json = schemas\structs\meta_eqdp.json
|
||||
schemas\structs\meta_eqp.json = schemas\structs\meta_eqp.json
|
||||
schemas\structs\meta_est.json = schemas\structs\meta_est.json
|
||||
schemas\structs\meta_geqp.json = schemas\structs\meta_geqp.json
|
||||
schemas\structs\meta_gmp.json = schemas\structs\meta_gmp.json
|
||||
schemas\structs\meta_imc.json = schemas\structs\meta_imc.json
|
||||
schemas\structs\meta_rsp.json = schemas\structs\meta_rsp.json
|
||||
schemas\structs\option.json = schemas\structs\option.json
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
|
@ -58,6 +86,10 @@ Global
|
|||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{BFEA7504-1210-4F79-A7FE-BF03B6567E33} = {F89C9EAE-25C8-43BE-8108-5921E5A93502}
|
||||
{B03F276A-0572-4F62-AF86-EF62F6B80463} = {BFEA7504-1210-4F79-A7FE-BF03B6567E33}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {B17E85B1-5F60-4440-9F9A-3DDE877E8CDF}
|
||||
EndGlobalSection
|
||||
|
|
|
|||
|
|
@ -27,6 +27,9 @@ public enum ModDataChangeType : ushort
|
|||
|
||||
public class ModDataEditor(SaveService saveService, CommunicatorService communicatorService) : IService
|
||||
{
|
||||
public SaveService SaveService
|
||||
=> saveService;
|
||||
|
||||
/// <summary> Create the file containing the meta information about a mod from scratch. </summary>
|
||||
public void CreateMeta(DirectoryInfo directory, string? name, string? author, string? description, string? version,
|
||||
string? website)
|
||||
|
|
@ -40,148 +43,6 @@ public class ModDataEditor(SaveService saveService, CommunicatorService communic
|
|||
saveService.ImmediateSaveSync(new ModMeta(mod));
|
||||
}
|
||||
|
||||
public ModDataChangeType LoadLocalData(Mod mod)
|
||||
{
|
||||
var dataFile = saveService.FileNames.LocalDataFile(mod);
|
||||
|
||||
var importDate = 0L;
|
||||
var localTags = Enumerable.Empty<string>();
|
||||
var favorite = false;
|
||||
var note = string.Empty;
|
||||
|
||||
var save = true;
|
||||
if (File.Exists(dataFile))
|
||||
try
|
||||
{
|
||||
var text = File.ReadAllText(dataFile);
|
||||
var json = JObject.Parse(text);
|
||||
|
||||
importDate = json[nameof(Mod.ImportDate)]?.Value<long>() ?? importDate;
|
||||
favorite = json[nameof(Mod.Favorite)]?.Value<bool>() ?? favorite;
|
||||
note = json[nameof(Mod.Note)]?.Value<string>() ?? note;
|
||||
localTags = (json[nameof(Mod.LocalTags)] as JArray)?.Values<string>().OfType<string>() ?? localTags;
|
||||
save = false;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Penumbra.Log.Error($"Could not load local mod data:\n{e}");
|
||||
}
|
||||
|
||||
if (importDate == 0)
|
||||
importDate = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
|
||||
|
||||
ModDataChangeType changes = 0;
|
||||
if (mod.ImportDate != importDate)
|
||||
{
|
||||
mod.ImportDate = importDate;
|
||||
changes |= ModDataChangeType.ImportDate;
|
||||
}
|
||||
|
||||
changes |= ModLocalData.UpdateTags(mod, null, localTags);
|
||||
|
||||
if (mod.Favorite != favorite)
|
||||
{
|
||||
mod.Favorite = favorite;
|
||||
changes |= ModDataChangeType.Favorite;
|
||||
}
|
||||
|
||||
if (mod.Note != note)
|
||||
{
|
||||
mod.Note = note;
|
||||
changes |= ModDataChangeType.Note;
|
||||
}
|
||||
|
||||
if (save)
|
||||
saveService.QueueSave(new ModLocalData(mod));
|
||||
|
||||
return changes;
|
||||
}
|
||||
|
||||
public ModDataChangeType LoadMeta(ModCreator creator, Mod mod)
|
||||
{
|
||||
var metaFile = saveService.FileNames.ModMetaPath(mod);
|
||||
if (!File.Exists(metaFile))
|
||||
{
|
||||
Penumbra.Log.Debug($"No mod meta found for {mod.ModPath.Name}.");
|
||||
return ModDataChangeType.Deletion;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var text = File.ReadAllText(metaFile);
|
||||
var json = JObject.Parse(text);
|
||||
|
||||
var newName = json[nameof(Mod.Name)]?.Value<string>() ?? string.Empty;
|
||||
var newAuthor = json[nameof(Mod.Author)]?.Value<string>() ?? string.Empty;
|
||||
var newDescription = json[nameof(Mod.Description)]?.Value<string>() ?? string.Empty;
|
||||
var newImage = json[nameof(Mod.Image)]?.Value<string>() ?? string.Empty;
|
||||
var newVersion = json[nameof(Mod.Version)]?.Value<string>() ?? string.Empty;
|
||||
var newWebsite = json[nameof(Mod.Website)]?.Value<string>() ?? string.Empty;
|
||||
var newFileVersion = json[nameof(ModMeta.FileVersion)]?.Value<uint>() ?? 0;
|
||||
var importDate = json[nameof(Mod.ImportDate)]?.Value<long>();
|
||||
var modTags = (json[nameof(Mod.ModTags)] as JArray)?.Values<string>().OfType<string>();
|
||||
|
||||
ModDataChangeType changes = 0;
|
||||
if (mod.Name != newName)
|
||||
{
|
||||
changes |= ModDataChangeType.Name;
|
||||
mod.Name = newName;
|
||||
}
|
||||
|
||||
if (mod.Author != newAuthor)
|
||||
{
|
||||
changes |= ModDataChangeType.Author;
|
||||
mod.Author = newAuthor;
|
||||
}
|
||||
|
||||
if (mod.Description != newDescription)
|
||||
{
|
||||
changes |= ModDataChangeType.Description;
|
||||
mod.Description = newDescription;
|
||||
}
|
||||
|
||||
if (mod.Image != newImage)
|
||||
{
|
||||
changes |= ModDataChangeType.Image;
|
||||
mod.Image = newImage;
|
||||
}
|
||||
|
||||
if (mod.Version != newVersion)
|
||||
{
|
||||
changes |= ModDataChangeType.Version;
|
||||
mod.Version = newVersion;
|
||||
}
|
||||
|
||||
if (mod.Website != newWebsite)
|
||||
{
|
||||
changes |= ModDataChangeType.Website;
|
||||
mod.Website = newWebsite;
|
||||
}
|
||||
|
||||
if (newFileVersion != ModMeta.FileVersion)
|
||||
if (ModMigration.Migrate(creator, saveService, mod, json, ref newFileVersion))
|
||||
{
|
||||
changes |= ModDataChangeType.Migration;
|
||||
saveService.ImmediateSave(new ModMeta(mod));
|
||||
}
|
||||
|
||||
if (importDate != null && mod.ImportDate != importDate.Value)
|
||||
{
|
||||
mod.ImportDate = importDate.Value;
|
||||
changes |= ModDataChangeType.ImportDate;
|
||||
}
|
||||
|
||||
changes |= ModLocalData.UpdateTags(mod, modTags, null);
|
||||
|
||||
return changes;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Penumbra.Log.Error($"Could not load mod meta for {metaFile}:\n{e}");
|
||||
return ModDataChangeType.Deletion;
|
||||
}
|
||||
}
|
||||
|
||||
public void ChangeModName(Mod mod, string newName)
|
||||
{
|
||||
if (mod.Name.Text == newName)
|
||||
|
|
|
|||
|
|
@ -72,11 +72,11 @@ public partial class ModCreator(
|
|||
if (!Directory.Exists(mod.ModPath.FullName))
|
||||
return false;
|
||||
|
||||
modDataChange = dataEditor.LoadMeta(this, mod);
|
||||
modDataChange = ModMeta.Load(dataEditor, this, mod);
|
||||
if (modDataChange.HasFlag(ModDataChangeType.Deletion) || mod.Name.Length == 0)
|
||||
return false;
|
||||
|
||||
modDataChange |= dataEditor.LoadLocalData(mod);
|
||||
modDataChange |= ModLocalData.Load(dataEditor, mod);
|
||||
LoadDefaultOption(mod);
|
||||
LoadAllGroups(mod);
|
||||
if (incorporateMetaChanges)
|
||||
|
|
|
|||
|
|
@ -27,6 +27,63 @@ public readonly struct ModLocalData(Mod mod) : ISavable
|
|||
jObject.WriteTo(jWriter);
|
||||
}
|
||||
|
||||
public static ModDataChangeType Load(ModDataEditor editor, Mod mod)
|
||||
{
|
||||
var dataFile = editor.SaveService.FileNames.LocalDataFile(mod);
|
||||
|
||||
var importDate = 0L;
|
||||
var localTags = Enumerable.Empty<string>();
|
||||
var favorite = false;
|
||||
var note = string.Empty;
|
||||
|
||||
var save = true;
|
||||
if (File.Exists(dataFile))
|
||||
try
|
||||
{
|
||||
var text = File.ReadAllText(dataFile);
|
||||
var json = JObject.Parse(text);
|
||||
|
||||
importDate = json[nameof(Mod.ImportDate)]?.Value<long>() ?? importDate;
|
||||
favorite = json[nameof(Mod.Favorite)]?.Value<bool>() ?? favorite;
|
||||
note = json[nameof(Mod.Note)]?.Value<string>() ?? note;
|
||||
localTags = (json[nameof(Mod.LocalTags)] as JArray)?.Values<string>().OfType<string>() ?? localTags;
|
||||
save = false;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Penumbra.Log.Error($"Could not load local mod data:\n{e}");
|
||||
}
|
||||
|
||||
if (importDate == 0)
|
||||
importDate = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
|
||||
|
||||
ModDataChangeType changes = 0;
|
||||
if (mod.ImportDate != importDate)
|
||||
{
|
||||
mod.ImportDate = importDate;
|
||||
changes |= ModDataChangeType.ImportDate;
|
||||
}
|
||||
|
||||
changes |= ModLocalData.UpdateTags(mod, null, localTags);
|
||||
|
||||
if (mod.Favorite != favorite)
|
||||
{
|
||||
mod.Favorite = favorite;
|
||||
changes |= ModDataChangeType.Favorite;
|
||||
}
|
||||
|
||||
if (mod.Note != note)
|
||||
{
|
||||
mod.Note = note;
|
||||
changes |= ModDataChangeType.Note;
|
||||
}
|
||||
|
||||
if (save)
|
||||
editor.SaveService.QueueSave(new ModLocalData(mod));
|
||||
|
||||
return changes;
|
||||
}
|
||||
|
||||
internal static ModDataChangeType UpdateTags(Mod mod, IEnumerable<string>? newModTags, IEnumerable<string>? newLocalTags)
|
||||
{
|
||||
if (newModTags == null && newLocalTags == null)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Penumbra.Mods.Editor;
|
||||
using Penumbra.Mods.Manager;
|
||||
using Penumbra.Services;
|
||||
|
||||
namespace Penumbra.Mods;
|
||||
|
|
@ -28,4 +30,85 @@ public readonly struct ModMeta(Mod mod) : ISavable
|
|||
jWriter.Formatting = Formatting.Indented;
|
||||
jObject.WriteTo(jWriter);
|
||||
}
|
||||
|
||||
public static ModDataChangeType Load(ModDataEditor editor, ModCreator creator, Mod mod)
|
||||
{
|
||||
var metaFile = editor.SaveService.FileNames.ModMetaPath(mod);
|
||||
if (!File.Exists(metaFile))
|
||||
{
|
||||
Penumbra.Log.Debug($"No mod meta found for {mod.ModPath.Name}.");
|
||||
return ModDataChangeType.Deletion;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var text = File.ReadAllText(metaFile);
|
||||
var json = JObject.Parse(text);
|
||||
|
||||
var newFileVersion = json[nameof(FileVersion)]?.Value<uint>() ?? 0;
|
||||
|
||||
// Empty name gets checked after loading and is not allowed.
|
||||
var newName = json[nameof(Mod.Name)]?.Value<string>() ?? string.Empty;
|
||||
|
||||
var newAuthor = json[nameof(Mod.Author)]?.Value<string>() ?? string.Empty;
|
||||
var newDescription = json[nameof(Mod.Description)]?.Value<string>() ?? string.Empty;
|
||||
var newImage = json[nameof(Mod.Image)]?.Value<string>() ?? string.Empty;
|
||||
var newVersion = json[nameof(Mod.Version)]?.Value<string>() ?? string.Empty;
|
||||
var newWebsite = json[nameof(Mod.Website)]?.Value<string>() ?? string.Empty;
|
||||
var modTags = (json[nameof(Mod.ModTags)] as JArray)?.Values<string>().OfType<string>();
|
||||
|
||||
ModDataChangeType changes = 0;
|
||||
if (mod.Name != newName)
|
||||
{
|
||||
changes |= ModDataChangeType.Name;
|
||||
mod.Name = newName;
|
||||
}
|
||||
|
||||
if (mod.Author != newAuthor)
|
||||
{
|
||||
changes |= ModDataChangeType.Author;
|
||||
mod.Author = newAuthor;
|
||||
}
|
||||
|
||||
if (mod.Description != newDescription)
|
||||
{
|
||||
changes |= ModDataChangeType.Description;
|
||||
mod.Description = newDescription;
|
||||
}
|
||||
|
||||
if (mod.Image != newImage)
|
||||
{
|
||||
changes |= ModDataChangeType.Image;
|
||||
mod.Image = newImage;
|
||||
}
|
||||
|
||||
if (mod.Version != newVersion)
|
||||
{
|
||||
changes |= ModDataChangeType.Version;
|
||||
mod.Version = newVersion;
|
||||
}
|
||||
|
||||
if (mod.Website != newWebsite)
|
||||
{
|
||||
changes |= ModDataChangeType.Website;
|
||||
mod.Website = newWebsite;
|
||||
}
|
||||
|
||||
if (newFileVersion != FileVersion)
|
||||
if (ModMigration.Migrate(creator, editor.SaveService, mod, json, ref newFileVersion))
|
||||
{
|
||||
changes |= ModDataChangeType.Migration;
|
||||
editor.SaveService.ImmediateSave(new ModMeta(mod));
|
||||
}
|
||||
|
||||
changes |= ModLocalData.UpdateTags(mod, modTags, null);
|
||||
|
||||
return changes;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Penumbra.Log.Error($"Could not load mod meta for {metaFile}:\n{e}");
|
||||
return ModDataChangeType.Deletion;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
19
schemas/default_mod.json
Normal file
19
schemas/default_mod.json
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"allOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"Version": {
|
||||
"description": "Mod Container version, currently unused.",
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"maximum": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"$ref": "structs/container.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
57
schemas/group.json
Normal file
57
schemas/group.json
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"Version": {
|
||||
"description": "Mod Container version, currently unused.",
|
||||
"type": "integer"
|
||||
},
|
||||
"Name": {
|
||||
"description": "Name of the group.",
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"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"
|
||||
},
|
||||
"Priority": {
|
||||
"description": "Priority of the group. If several groups define conflicting files or manipulations, the highest priority wins.",
|
||||
"type": "integer"
|
||||
},
|
||||
"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": [
|
||||
{
|
||||
"$ref": "structs/group_combining.json"
|
||||
},
|
||||
{
|
||||
"$ref": "structs/group_imc.json"
|
||||
},
|
||||
{
|
||||
"$ref": "structs/group_multi.json"
|
||||
},
|
||||
{
|
||||
"$ref": "structs/group_single.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
32
schemas/local_mod_data-v3.json
Normal file
32
schemas/local_mod_data-v3.json
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"title": "Local Penumbra Mod Data",
|
||||
"description": "The locally stored data for an installed mod in Penumbra",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"FileVersion": {
|
||||
"description": "Major version of the local data schema used.",
|
||||
"type": "integer",
|
||||
"minimum": 3,
|
||||
"maximum": 3
|
||||
},
|
||||
"ImportDate": {
|
||||
"description": "The date and time of the installation of the mod as a Unix Epoch millisecond timestamp.",
|
||||
"type": "integer"
|
||||
},
|
||||
"LocalTags": {
|
||||
"description": "User-defined local tags for the mod.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"uniqueItems": true
|
||||
},
|
||||
"Favorite": {
|
||||
"description": "Whether the mod is favourited by the user.",
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"required": [ "FileVersion" ]
|
||||
}
|
||||
52
schemas/mod_meta-v3.json
Normal file
52
schemas/mod_meta-v3.json
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"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",
|
||||
"minLength": 1
|
||||
},
|
||||
"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",
|
||||
"minLength": 1
|
||||
},
|
||||
"uniqueItems": true
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"FileVersion",
|
||||
"Name"
|
||||
]
|
||||
}
|
||||
499
schemas/shpk_devkit.json
Normal file
499
schemas/shpk_devkit.json
Normal file
|
|
@ -0,0 +1,499 @@
|
|||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"ShaderKeys": {
|
||||
"type": "object",
|
||||
"patternProperties": {
|
||||
"^\\d+$": {
|
||||
"$ref": "#/$defs/ShaderKey"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"Comment": {
|
||||
"$ref": "#/$defs/MayVary<string>"
|
||||
},
|
||||
"Samplers": {
|
||||
"type": "object",
|
||||
"patternProperties": {
|
||||
"^\\d+$": {
|
||||
"$ref": "#/$defs/MayVary<Sampler>"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"Constants": {
|
||||
"type": "object",
|
||||
"patternProperties": {
|
||||
"^\\d+$": {
|
||||
"$ref": "#/$defs/MayVary<Constant[]>"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"$defs": {
|
||||
"ShaderKeyValue": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"Label": {
|
||||
"type": "string"
|
||||
},
|
||||
"Description": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"ShaderKey": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"Label": {
|
||||
"type": "string"
|
||||
},
|
||||
"Description": {
|
||||
"type": "string"
|
||||
},
|
||||
"Values": {
|
||||
"type": "object",
|
||||
"patternProperties": {
|
||||
"^\\d+$": {
|
||||
"$ref": "#/$defs/ShaderKeyValue"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"Varying<any>": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"Vary": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/$defs/LaxInteger"
|
||||
}
|
||||
},
|
||||
"Selectors": {
|
||||
"description": "Keys are Σ 31^i shaderKey(Vary[i]).",
|
||||
"type": "object",
|
||||
"patternProperties": {
|
||||
"^\\d+$": {
|
||||
"type": "integer"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"Items": {
|
||||
"type": "array",
|
||||
"$comment": "Varying<T> is defined by constraining this array's items to T"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"Vary",
|
||||
"Selectors",
|
||||
"Items"
|
||||
],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"MayVary<string>": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": ["string", "null"]
|
||||
}, {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/$defs/Varying<any>"
|
||||
}, {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"Items": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": ["string", "null"]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"Sampler": {
|
||||
"type": ["object", "null"],
|
||||
"properties": {
|
||||
"Label": {
|
||||
"type": "string"
|
||||
},
|
||||
"Description": {
|
||||
"type": "string"
|
||||
},
|
||||
"DefaultTexture": {
|
||||
"type": "string",
|
||||
"pattern": "^[^/\\\\][^\\\\]*$"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"MayVary<Sampler>": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "#/$defs/Sampler"
|
||||
}, {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/$defs/Varying<any>"
|
||||
}, {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"Items": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/$defs/Sampler"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"ConstantBase": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"Offset": {
|
||||
"description": "Defaults to 0. Mutually exclusive with ByteOffset.",
|
||||
"type": "integer",
|
||||
"minimum": 0
|
||||
},
|
||||
"Length": {
|
||||
"description": "Defaults to up to the end. Mutually exclusive with ByteLength.",
|
||||
"type": "integer",
|
||||
"minimum": 0
|
||||
},
|
||||
"ByteOffset": {
|
||||
"description": "Defaults to 0. Mutually exclusive with Offset.",
|
||||
"type": "integer",
|
||||
"minimum": 0
|
||||
},
|
||||
"ByteLength": {
|
||||
"description": "Defaults to up to the end. Mutually exclusive with Length.",
|
||||
"type": "integer",
|
||||
"minimum": 0
|
||||
},
|
||||
"Group": {
|
||||
"description": "Defaults to \"Further Constants\".",
|
||||
"type": "string"
|
||||
},
|
||||
"Label": {
|
||||
"type": "string"
|
||||
},
|
||||
"Description": {
|
||||
"description": "Defaults to empty.",
|
||||
"type": "string"
|
||||
},
|
||||
"Type": {
|
||||
"description": "Defaults to Float.",
|
||||
"enum": ["Hidden", "Float", "Integer", "Color", "Enum", "Int32", "Int32Enum", "Int8", "Int8Enum", "Int16", "Int16Enum", "Int64", "Int64Enum", "Half", "Double", "TileIndex", "SphereMapIndex"]
|
||||
}
|
||||
},
|
||||
"not": {
|
||||
"anyOf": [
|
||||
{
|
||||
"required": ["Offset", "ByteOffset"]
|
||||
}, {
|
||||
"required": ["Length", "ByteLenngth"]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"HiddenConstant": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"Type": {
|
||||
"const": "Hidden"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"Type"
|
||||
],
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/$defs/ConstantBase"
|
||||
}
|
||||
],
|
||||
"unevaluatedProperties": false
|
||||
},
|
||||
"FloatConstant": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"Type": {
|
||||
"enum": ["Float", "Half", "Double"]
|
||||
},
|
||||
"Minimum": {
|
||||
"description": "Defaults to -∞.",
|
||||
"type": "number"
|
||||
},
|
||||
"Maximum": {
|
||||
"description": "Defaults to ∞.",
|
||||
"type": "number"
|
||||
},
|
||||
"Speed": {
|
||||
"description": "Defaults to 0.1.",
|
||||
"type": "number",
|
||||
"minimum": 0
|
||||
},
|
||||
"RelativeSpeed": {
|
||||
"description": "Defaults to 0.",
|
||||
"type": "number",
|
||||
"minimum": 0
|
||||
},
|
||||
"Exponent": {
|
||||
"description": "Defaults to 1. Uses an odd pseudo-power function, f(x) = sgn(x) |x|^n.",
|
||||
"type": "number"
|
||||
},
|
||||
"Factor": {
|
||||
"description": "Defaults to 1.",
|
||||
"type": "number"
|
||||
},
|
||||
"Bias": {
|
||||
"description": "Defaults to 0.",
|
||||
"type": "number"
|
||||
},
|
||||
"Precision": {
|
||||
"description": "Defaults to 3.",
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"maximum": 9
|
||||
},
|
||||
"Slider": {
|
||||
"description": "Defaults to true. Drag has priority over this.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"Drag": {
|
||||
"description": "Defaults to true. Has priority over Slider.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"Unit": {
|
||||
"description": "Defaults to no unit.",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"Label"
|
||||
],
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/$defs/ConstantBase"
|
||||
}
|
||||
],
|
||||
"unevaluatedProperties": false
|
||||
},
|
||||
"IntConstant": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"Type": {
|
||||
"enum": ["Integer", "Int32", "Int8", "Int16", "Int64"]
|
||||
},
|
||||
"Minimum": {
|
||||
"description": "Defaults to -2^N, N being the explicit integer width specified in the type, or 32 for Int.",
|
||||
"type": "number"
|
||||
},
|
||||
"Maximum": {
|
||||
"description": "Defaults to 2^N - 1, N being the explicit integer width specified in the type, or 32 for Int.",
|
||||
"type": "number"
|
||||
},
|
||||
"Speed": {
|
||||
"description": "Defaults to 0.25.",
|
||||
"type": "number",
|
||||
"minimum": 0
|
||||
},
|
||||
"RelativeSpeed": {
|
||||
"description": "Defaults to 0.",
|
||||
"type": "number",
|
||||
"minimum": 0
|
||||
},
|
||||
"Factor": {
|
||||
"description": "Defaults to 1.",
|
||||
"type": "number"
|
||||
},
|
||||
"Bias": {
|
||||
"description": "Defaults to 0.",
|
||||
"type": "number"
|
||||
},
|
||||
"Hex": {
|
||||
"description": "Defaults to false. Has priority over Slider and Drag.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"Slider": {
|
||||
"description": "Defaults to true. Hex and Drag have priority over this.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"Drag": {
|
||||
"description": "Defaults to true. Has priority over Slider, but Hex has priority over this.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"Unit": {
|
||||
"description": "Defaults to no unit.",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"Label",
|
||||
"Type"
|
||||
],
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/$defs/ConstantBase"
|
||||
}
|
||||
],
|
||||
"unevaluatedProperties": false
|
||||
},
|
||||
"ColorConstant": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"Type": {
|
||||
"const": "Color"
|
||||
},
|
||||
"SquaredRgb": {
|
||||
"description": "Defaults to false. Uses an odd pseudo-square function, f(x) = sgn(x) |x|².",
|
||||
"type": "boolean"
|
||||
},
|
||||
"Clamped": {
|
||||
"description": "Defaults to false.",
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"Label",
|
||||
"Type"
|
||||
],
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/$defs/ConstantBase"
|
||||
}
|
||||
],
|
||||
"unevaluatedProperties": false
|
||||
},
|
||||
"EnumValue": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"Label": {
|
||||
"type": "string"
|
||||
},
|
||||
"Description": {
|
||||
"type": "string"
|
||||
},
|
||||
"Value": {
|
||||
"type": "number"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"Label",
|
||||
"Value"
|
||||
],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"EnumConstant": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"Type": {
|
||||
"enum": ["Enum", "Int32Enum", "Int8Enum", "Int16Enum", "Int64Enum"]
|
||||
},
|
||||
"Values": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/$defs/EnumValue"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"Label",
|
||||
"Type"
|
||||
],
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/$defs/ConstantBase"
|
||||
}
|
||||
],
|
||||
"unevaluatedProperties": false
|
||||
},
|
||||
"SpecialConstant": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"Type": {
|
||||
"enum": ["TileIndex", "SphereMapIndex"]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"Label",
|
||||
"Type"
|
||||
],
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/$defs/ConstantBase"
|
||||
}
|
||||
],
|
||||
"unevaluatedProperties": false
|
||||
},
|
||||
"Constant": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "#/$defs/HiddenConstant"
|
||||
}, {
|
||||
"$ref": "#/$defs/FloatConstant"
|
||||
}, {
|
||||
"$ref": "#/$defs/IntConstant"
|
||||
}, {
|
||||
"$ref": "#/$defs/ColorConstant"
|
||||
}, {
|
||||
"$ref": "#/$defs/EnumConstant"
|
||||
}, {
|
||||
"$ref": "#/$defs/SpecialConstant"
|
||||
}
|
||||
]
|
||||
},
|
||||
"MayVary<Constant[]>": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": ["array", "null"],
|
||||
"items": {
|
||||
"$ref": "#/$defs/Constant"
|
||||
}
|
||||
}, {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/$defs/Varying<any>"
|
||||
}, {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"Items": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": ["array", "null"],
|
||||
"items": {
|
||||
"$ref": "#/$defs/Constant"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"LaxInteger": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "integer"
|
||||
}, {
|
||||
"type": "string",
|
||||
"pattern": "^\\d+$"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
34
schemas/structs/container.json
Normal file
34
schemas/structs/container.json
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"Files": {
|
||||
"description": "File redirections in this container. Keys are game paths, values are relative file paths.",
|
||||
"type": [ "object", "null" ],
|
||||
"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", "null" ],
|
||||
"patternProperties": {
|
||||
"^[^/\\\\.?:][^\\\\?:]+$": {
|
||||
"type": "string",
|
||||
"pattern": "^[^/\\\\.:?][^?:]+$"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"Manipulations": {
|
||||
"type": [ "array", "null" ],
|
||||
"items": {
|
||||
"$ref": "manipulation.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
31
schemas/structs/group_combining.json
Normal file
31
schemas/structs/group_combining.json
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"properties": {
|
||||
"Type": {
|
||||
"const": "Combining"
|
||||
},
|
||||
"Options": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "option.json"
|
||||
}
|
||||
},
|
||||
"Containers": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "container.json"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"Name": {
|
||||
"type": [ "string", "null" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
50
schemas/structs/group_imc.json
Normal file
50
schemas/structs/group_imc.json
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"properties": {
|
||||
"Type": {
|
||||
"const": "Imc"
|
||||
},
|
||||
"AllVariants": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"OnlyAttributes": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"Identifier": {
|
||||
"$ref": "meta_imc.json#ImcIdentifier"
|
||||
},
|
||||
"DefaultEntry": {
|
||||
"$ref": "meta_imc.json#ImcEntry"
|
||||
},
|
||||
"Options": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "option.json",
|
||||
"oneOf": [
|
||||
{
|
||||
"properties": {
|
||||
"AttributeMask": {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"maximum": 1023
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"AttributeMask"
|
||||
]
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"IsDisableSubMod": {
|
||||
"const": true
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"IsDisableSubMod"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
32
schemas/structs/group_multi.json
Normal file
32
schemas/structs/group_multi.json
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"Type": {
|
||||
"const": "Multi"
|
||||
},
|
||||
"Options": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "option.json"
|
||||
},
|
||||
{
|
||||
"$ref": "container.json"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"Priority": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
22
schemas/structs/group_single.json
Normal file
22
schemas/structs/group_single.json
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"Type": {
|
||||
"const": "Single"
|
||||
},
|
||||
"Options": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "option.json"
|
||||
},
|
||||
{
|
||||
"$ref": "container.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
95
schemas/structs/manipulation.json
Normal file
95
schemas/structs/manipulation.json
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"Type": {
|
||||
"enum": [ "Unknown", "Imc", "Eqdp", "Eqp", "Est", "Gmp", "Rsp", "GlobalEqp", "Atch" ]
|
||||
},
|
||||
"Manipulation": {
|
||||
"type": "object"
|
||||
}
|
||||
},
|
||||
"required": [ "Type", "Manipulation" ],
|
||||
"oneOf": [
|
||||
{
|
||||
"properties": {
|
||||
"Type": {
|
||||
"const": "Imc"
|
||||
},
|
||||
"Manipulation": {
|
||||
"$ref": "meta_imc.json"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"Type": {
|
||||
"const": "Eqdp"
|
||||
},
|
||||
"Manipulation": {
|
||||
"$ref": "meta_eqdp.json"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"Type": {
|
||||
"const": "Eqp"
|
||||
},
|
||||
"Manipulation": {
|
||||
"$ref": "meta_eqp.json"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"Type": {
|
||||
"const": "Est"
|
||||
},
|
||||
"Manipulation": {
|
||||
"$ref": "meta_est.json"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"Type": {
|
||||
"const": "Gmp"
|
||||
},
|
||||
"Manipulation": {
|
||||
"$ref": "meta_gmp.json"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"Type": {
|
||||
"const": "Rsp"
|
||||
},
|
||||
"Manipulation": {
|
||||
"$ref": "meta_rsp.json"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"Type": {
|
||||
"const": "GlobalEqp"
|
||||
},
|
||||
"Manipulation": {
|
||||
"$ref": "meta_geqp.json"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"Type": {
|
||||
"const": "Atch"
|
||||
},
|
||||
"Manipulation": {
|
||||
"$ref": "meta_atch.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
67
schemas/structs/meta_atch.json
Normal file
67
schemas/structs/meta_atch.json
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"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"
|
||||
]
|
||||
},
|
||||
"Gender": {
|
||||
"$ref": "meta_enums.json#Gender"
|
||||
},
|
||||
"Race": {
|
||||
"$ref": "meta_enums.json#ModelRace"
|
||||
},
|
||||
"Type": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"maxLength": 4
|
||||
},
|
||||
"Index": {
|
||||
"$ref": "meta_enums.json#U16"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"Entry",
|
||||
"Gender",
|
||||
"Race",
|
||||
"Type",
|
||||
"Index"
|
||||
]
|
||||
}
|
||||
57
schemas/structs/meta_enums.json
Normal file
57
schemas/structs/meta_enums.json
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$defs": {
|
||||
"EquipSlot": {
|
||||
"$anchor": "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": {
|
||||
"$anchor": "Gender",
|
||||
"enum": [ "Unknown", "Male", "Female", "MaleNpc", "FemaleNpc" ]
|
||||
},
|
||||
"ModelRace": {
|
||||
"$anchor": "ModelRace",
|
||||
"enum": [ "Unknown", "Midlander", "Highlander", "Elezen", "Lalafell", "Miqote", "Roegadyn", "AuRa", "Hrothgar", "Viera" ]
|
||||
},
|
||||
"ObjectType": {
|
||||
"$anchor": "ObjectType",
|
||||
"enum": [ "Unknown", "Vfx", "DemiHuman", "Accessory", "World", "Housing", "Monster", "Icon", "LoadingScreen", "Map", "Interface", "Equipment", "Character", "Weapon", "Font" ]
|
||||
},
|
||||
"BodySlot": {
|
||||
"$anchor": "BodySlot",
|
||||
"enum": [ "Unknown", "Hair", "Face", "Tail", "Body", "Zear" ]
|
||||
},
|
||||
"SubRace": {
|
||||
"$anchor": "SubRace",
|
||||
"enum": [ "Unknown", "Midlander", "Highlander", "Wildwood", "Duskwight", "Plainsfolk", "Dunesfolk", "SeekerOfTheSun", "KeeperOfTheMoon", "Seawolf", "Hellsguard", "Raen", "Xaela", "Helion", "Lost", "Rava", "Veena" ]
|
||||
},
|
||||
"U8": {
|
||||
"$anchor": "U8",
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"maximum": 255
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"pattern": "^0*(1[0-9][0-9]|[0-9]?[0-9]|2[0-4][0-9]|25[0-5])$"
|
||||
}
|
||||
]
|
||||
},
|
||||
"U16": {
|
||||
"$anchor": "U16",
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"maximum": 65535
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"pattern": "^0*([1-5][0-9]{4}|[0-9]{0,4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])$"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
30
schemas/structs/meta_eqdp.json
Normal file
30
schemas/structs/meta_eqdp.json
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"Entry": {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"maximum": 1023
|
||||
},
|
||||
"Gender": {
|
||||
"$ref": "meta_enums.json#Gender"
|
||||
},
|
||||
"Race": {
|
||||
"$ref": "meta_enums.json#ModelRace"
|
||||
},
|
||||
"SetId": {
|
||||
"$ref": "meta_enums.json#U16"
|
||||
},
|
||||
"Slot": {
|
||||
"$ref": "meta_enums.json#EquipSlot"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"Entry",
|
||||
"Gender",
|
||||
"Race",
|
||||
"SetId",
|
||||
"Slot"
|
||||
]
|
||||
}
|
||||
20
schemas/structs/meta_eqp.json
Normal file
20
schemas/structs/meta_eqp.json
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"Entry": {
|
||||
"type": "integer"
|
||||
},
|
||||
"SetId": {
|
||||
"$ref": "meta_enums.json#U16"
|
||||
},
|
||||
"Slot": {
|
||||
"$ref": "meta_enums.json#EquipSlot"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"Entry",
|
||||
"SetId",
|
||||
"Slot"
|
||||
]
|
||||
}
|
||||
28
schemas/structs/meta_est.json
Normal file
28
schemas/structs/meta_est.json
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"Entry": {
|
||||
"$ref": "meta_enums.json#U16"
|
||||
},
|
||||
"Gender": {
|
||||
"$ref": "meta_enums.json#Gender"
|
||||
},
|
||||
"Race": {
|
||||
"$ref": "meta_enums.json#ModelRace"
|
||||
},
|
||||
"SetId": {
|
||||
"$ref": "meta_enums.json#U16"
|
||||
},
|
||||
"Slot": {
|
||||
"enum": [ "Hair", "Face", "Body", "Head" ]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"Entry",
|
||||
"Gender",
|
||||
"Race",
|
||||
"SetId",
|
||||
"Slot"
|
||||
]
|
||||
}
|
||||
40
schemas/structs/meta_geqp.json
Normal file
40
schemas/structs/meta_geqp.json
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"Condition": {
|
||||
"$ref": "meta_enums.json#U16"
|
||||
},
|
||||
"Type": {
|
||||
"enum": [ "DoNotHideEarrings", "DoNotHideNecklace", "DoNotHideBracelets", "DoNotHideRingR", "DoNotHideRingL", "DoNotHideHrothgarHats", "DoNotHideVieraHats" ]
|
||||
}
|
||||
},
|
||||
"required": [ "Type" ],
|
||||
"oneOf": [
|
||||
{
|
||||
"properties": {
|
||||
"Type": {
|
||||
"const": [ "DoNotHideHrothgarHats", "DoNotHideVieraHats" ]
|
||||
},
|
||||
"Condition": {
|
||||
"const": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"Type": {
|
||||
"const": [ "DoNotHideHrothgarHats", "DoNotHideVieraHats" ]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"Type": {
|
||||
"const": [ "DoNotHideEarrings", "DoNotHideNecklace", "DoNotHideBracelets", "DoNotHideRingR", "DoNotHideRingL" ]
|
||||
},
|
||||
"Condition": {}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
59
schemas/structs/meta_gmp.json
Normal file
59
schemas/structs/meta_gmp.json
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"Entry": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"Enabled": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"Animated": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"RotationA": {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"maximum": 1023
|
||||
},
|
||||
"RotationB": {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"maximum": 1023
|
||||
},
|
||||
"RotationC": {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"maximum": 1023
|
||||
},
|
||||
"UnknownA": {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"maximum": 15
|
||||
},
|
||||
"UnknownB": {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"maximum": 15
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"Enabled",
|
||||
"Animated",
|
||||
"RotationA",
|
||||
"RotationB",
|
||||
"RotationC",
|
||||
"UnknownA",
|
||||
"UnknownB"
|
||||
],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"SetId": {
|
||||
"$ref": "meta_enums.json#U16"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"Entry",
|
||||
"SetId"
|
||||
]
|
||||
}
|
||||
87
schemas/structs/meta_imc.json
Normal file
87
schemas/structs/meta_imc.json
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"Entry": {
|
||||
"$ref": "#ImcEntry"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"Entry"
|
||||
],
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#ImcIdentifier"
|
||||
}
|
||||
],
|
||||
"$defs": {
|
||||
"ImcIdentifier": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"PrimaryId": {
|
||||
"$ref": "meta_enums.json#U16"
|
||||
},
|
||||
"SecondaryId": {
|
||||
"$ref": "meta_enums.json#U16"
|
||||
},
|
||||
"Variant": {
|
||||
"$ref": "meta_enums.json#U8"
|
||||
},
|
||||
"ObjectType": {
|
||||
"$ref": "meta_enums.json#ObjectType"
|
||||
},
|
||||
"EquipSlot": {
|
||||
"$ref": "meta_enums.json#EquipSlot"
|
||||
},
|
||||
"BodySlot": {
|
||||
"$ref": "meta_enums.json#BodySlot"
|
||||
}
|
||||
},
|
||||
"$anchor": "ImcIdentifier",
|
||||
"required": [
|
||||
"PrimaryId",
|
||||
"SecondaryId",
|
||||
"Variant",
|
||||
"ObjectType",
|
||||
"EquipSlot",
|
||||
"BodySlot"
|
||||
]
|
||||
},
|
||||
"ImcEntry": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"MaterialId": {
|
||||
"$ref": "meta_enums.json#U8"
|
||||
},
|
||||
"DecalId": {
|
||||
"$ref": "meta_enums.json#U8"
|
||||
},
|
||||
"VfxId": {
|
||||
"$ref": "meta_enums.json#U8"
|
||||
},
|
||||
"MaterialAnimationId": {
|
||||
"$ref": "meta_enums.json#U8"
|
||||
},
|
||||
"AttributeMask": {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"maximum": 1023
|
||||
},
|
||||
"SoundId": {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"maximum": 63
|
||||
}
|
||||
},
|
||||
"$anchor": "ImcEntry",
|
||||
"required": [
|
||||
"MaterialId",
|
||||
"DecalId",
|
||||
"VfxId",
|
||||
"MaterialAnimationId",
|
||||
"AttributeMask",
|
||||
"SoundId"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
20
schemas/structs/meta_rsp.json
Normal file
20
schemas/structs/meta_rsp.json
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"Entry": {
|
||||
"type": "number"
|
||||
},
|
||||
"SubRace": {
|
||||
"$ref": "meta_enums.json#SubRace"
|
||||
},
|
||||
"Attribute": {
|
||||
"enum": [ "MaleMinSize", "MaleMaxSize", "MaleMinTail", "MaleMaxTail", "FemaleMinSize", "FemaleMaxSize", "FemaleMinTail", "FemaleMaxTail", "BustMinX", "BustMinY", "BustMinZ", "BustMaxX", "BustMaxY", "BustMaxZ" ]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"Entry",
|
||||
"SubRace",
|
||||
"Attribute"
|
||||
]
|
||||
}
|
||||
24
schemas/structs/option.json
Normal file
24
schemas/structs/option.json
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"Name": {
|
||||
"description": "Name of the option.",
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"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"
|
||||
},
|
||||
"Image": {
|
||||
"description": "Unused by Penumbra.",
|
||||
"type": [ "string", "null" ]
|
||||
}
|
||||
},
|
||||
"required": [ "Name" ]
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue