@minecraft/creator-tools
Version:
Minecraft Creator Tools command line and libraries.
966 lines (965 loc) • 49.1 kB
JavaScript
"use strict";
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const Project_1 = require("./Project");
const ProjectContent_1 = __importDefault(require("./ProjectContent"));
const IProjectData_1 = require("./IProjectData");
const IProjectItemData_1 = require("./IProjectItemData");
const StorageUtilities_1 = __importDefault(require("./../storage/StorageUtilities"));
const ZipStorage_1 = __importDefault(require("../storage/ZipStorage"));
const ProjectItemUtilities_1 = __importDefault(require("./ProjectItemUtilities"));
const ProjectAutogeneration_1 = __importDefault(require("./ProjectAutogeneration"));
const Database_1 = __importDefault(require("../minecraft/Database"));
const Log_1 = __importDefault(require("../core/Log"));
const SoundDefinitionCatalogDefinition_1 = __importDefault(require("../minecraft/SoundDefinitionCatalogDefinition"));
const SoundCatalogDefinition_1 = __importDefault(require("../minecraft/SoundCatalogDefinition"));
const MinecraftUtilities_1 = __importDefault(require("../minecraft/MinecraftUtilities"));
const IGalleryItem_1 = require("./IGalleryItem");
const ProjectUtilities_1 = require("./ProjectUtilities");
const ImageEditsDefinition_1 = __importDefault(require("../design/ImageEditsDefinition"));
const ProjectCreateManager_1 = __importDefault(require("./ProjectCreateManager"));
/// Does create operations for project items.
class ProjectItemCreateManager {
static async _getDefaultBehaviorPackPath(project) {
const bpFolder = await project.ensureDefaultBehaviorPackFolder();
if (project.projectFolder === null) {
return undefined;
}
const defaultPath = bpFolder.getFolderRelativePath(project.projectFolder);
return defaultPath;
}
static async _getDefaultBehaviorPackFolderPath(project, name) {
const bpFolder = await project.ensureDefaultBehaviorPackFolder();
if (project.projectFolder === null) {
return undefined;
}
const subfolder = bpFolder.ensureFolder(name);
await subfolder.ensureExists();
const defaultPath = subfolder.getFolderRelativePath(project.projectFolder);
return defaultPath;
}
static async _getDefaultDesignPackFolderPath(project, name) {
const dpFolder = await project.ensureDefaultDesignPackFolder();
if (project.projectFolder === null) {
return undefined;
}
const subfolder = dpFolder.ensureFolder(name);
await subfolder.ensureExists();
const defaultPath = subfolder.getFolderRelativePath(project.projectFolder);
return defaultPath;
}
static async _getDefaultResourcePackPath(project) {
const rpFolder = await project.ensureDefaultResourcePackFolder();
if (project.projectFolder === null) {
return undefined;
}
const defaultPath = rpFolder.getFolderRelativePath(project.projectFolder);
return defaultPath;
}
static async _getDefaultResourcePackFolderPath(project, name) {
const rpFolder = await project.ensureDefaultResourcePackFolder();
if (project.projectFolder === null) {
return undefined;
}
const subfolder = rpFolder.ensureFolder(name);
await subfolder.ensureExists();
const defaultPath = subfolder.getFolderRelativePath(project.projectFolder);
return defaultPath;
}
static async _getDefaultScriptsFolderPath(project) {
const scriptsFolder = await project.ensureMainScriptsFolder();
if (project.projectFolder === null) {
return undefined;
}
const defaultPath = scriptsFolder.getFolderRelativePath(project.projectFolder);
return defaultPath;
}
static async createNewItem(project, itemSeed) {
if (itemSeed.name === "" || itemSeed.name === undefined) {
itemSeed.name = ProjectItemUtilities_1.default.getNewItemName(itemSeed.itemType);
}
let creationData = itemSeed.creationData;
if (creationData) {
creationData = ProjectCreateManager_1.default.getReplacedCreationDataInObject(project, creationData, itemSeed.name);
}
if (itemSeed.itemType) {
switch (itemSeed.itemType) {
case IProjectItemData_1.ProjectItemType.js:
case IProjectItemData_1.ProjectItemType.ts:
return ProjectItemCreateManager.createNewScript(project, itemSeed.itemType, itemSeed.name, itemSeed.folder);
case IProjectItemData_1.ProjectItemType.dataForm:
return ProjectItemCreateManager.createNewForm(project, itemSeed.name, itemSeed.folder);
case IProjectItemData_1.ProjectItemType.audio:
return ProjectItemCreateManager.createNewAudio(project, itemSeed.name, itemSeed.folder);
case IProjectItemData_1.ProjectItemType.texture:
return ProjectItemCreateManager.createNewTexture(project, itemSeed.name, itemSeed.folder);
case IProjectItemData_1.ProjectItemType.designTexture:
return ProjectItemCreateManager.createNewDesignTexture(project, itemSeed.name, itemSeed.folder, creationData);
}
}
if (ProjectItemUtilities_1.default.isBehaviorRelated(itemSeed.itemType)) {
return await ProjectItemCreateManager.createBehaviorPackJsonItem(project, itemSeed);
}
else if (ProjectItemUtilities_1.default.isResourceRelated(itemSeed.itemType)) {
return await ProjectItemCreateManager.createResourcePackJsonItem(project, itemSeed);
}
else if (ProjectItemUtilities_1.default.isDesignRelated(itemSeed.itemType)) {
return await ProjectItemCreateManager.createDesignPackJsonItem(project, itemSeed);
}
Log_1.default.error("No creation handler for item type: " + itemSeed.itemType);
return undefined;
}
static async createNewScript(project, itemType, name, folder) {
let defaultPath = undefined;
if (folder && project.projectFolder) {
defaultPath = folder.getFolderRelativePath(project.projectFolder);
}
else {
defaultPath = await ProjectItemCreateManager._getDefaultScriptsFolderPath(project);
}
if (defaultPath === undefined) {
return;
}
const candidateFilePath = await ProjectItemCreateManager._generateFileNameForNewItem(project, defaultPath, name, itemType === IProjectItemData_1.ProjectItemType.js ? "js" : "ts");
if (candidateFilePath === undefined) {
return;
}
const pi = project.ensureItemByProjectPath(candidateFilePath, IProjectItemData_1.ProjectItemStorageType.singleFile, StorageUtilities_1.default.getLeafName(candidateFilePath), itemType === IProjectItemData_1.ProjectItemType.js ? IProjectItemData_1.ProjectItemType.js : IProjectItemData_1.ProjectItemType.ts, Project_1.FolderContext.behaviorPack, undefined, IProjectItemData_1.ProjectItemCreationType.normal);
const file = await pi.loadFileContent();
if (file !== null) {
const baseName = StorageUtilities_1.default.getBaseFromName(file.name);
if (project.preferredScriptLanguage === IProjectData_1.ProjectScriptLanguage.typeScript) {
file.setContent(ProjectContent_1.default.getEmptyTypeScript(project.name, baseName));
}
else {
file.setContent(ProjectContent_1.default.getEmptyJavaScript(project.name, baseName));
}
}
await ProjectAutogeneration_1.default.updateProjectAutogeneration(project, false);
await project.save();
return pi;
}
static async _generateFolderNameForNewItem(project, basePath, baseName) {
if (project.projectFolder === null) {
return undefined;
}
let index = 0;
let candidateFolderPath = "";
let finalPathPrefix = "";
const projectFolder = project.projectFolder;
let candidateFolder = null;
let hash = basePath.indexOf("#");
let targetFolder = projectFolder;
while (hash > 0) {
// dig into container files if needed.
let containerFilePath = basePath.substring(0, hash);
basePath = basePath.substring(hash + 1);
hash = basePath.indexOf("#");
if (containerFilePath.startsWith(targetFolder.fullPath)) {
containerFilePath = containerFilePath.substring(targetFolder.fullPath.length);
}
finalPathPrefix += containerFilePath + "#";
const containerFile = await targetFolder.getFileFromRelativePath(containerFilePath);
if (!containerFile) {
return undefined;
}
const extension = containerFile.type;
if (extension !== "zip" && extension !== "mcworld" && extension !== "mctemplate") {
return undefined;
}
if (!containerFile.fileContainerStorage) {
const zipStorage = new ZipStorage_1.default();
if (!containerFile.isContentLoaded) {
await containerFile.loadContent();
}
if (!containerFile.content || !(containerFile.content instanceof Uint8Array)) {
return undefined;
}
await zipStorage.loadFromUint8Array(containerFile.content, containerFile.name);
zipStorage.containerFile = containerFile;
containerFile.fileContainerStorage = zipStorage;
containerFile.fileContainerStorage.storagePath = containerFilePath + "#";
}
targetFolder = containerFile.fileContainerStorage.rootFolder;
}
await targetFolder.ensureFolderFromRelativePath(basePath);
await targetFolder.ensureExists();
// find a folder name not in use
do {
index++;
candidateFolderPath = basePath + baseName + index;
candidateFolder = await targetFolder.getFolderFromRelativePath(candidateFolderPath);
} while (candidateFolder !== null && candidateFolder !== undefined);
return finalPathPrefix + candidateFolderPath;
}
static async _generateFileNameForNewItem(project, basePath, baseName, extension) {
if (project.projectFolder === null) {
return undefined;
}
let index = 0;
let candidateFilePath = "";
let finalPathPrefix = "";
const projectFolder = project.projectFolder;
let candidateFile = null;
let hash = basePath.indexOf("#");
let targetFolder = projectFolder;
while (hash > 0) {
// dig into container files if needed.
let containerFilePath = basePath.substring(0, hash);
basePath = basePath.substring(hash + 1);
hash = basePath.indexOf("#");
if (containerFilePath.startsWith(targetFolder.fullPath)) {
containerFilePath = containerFilePath.substring(targetFolder.fullPath.length);
}
finalPathPrefix += containerFilePath + "#";
const containerFile = await targetFolder.getFileFromRelativePath(containerFilePath);
if (!containerFile) {
return undefined;
}
const extension = containerFile.type;
if (extension !== "zip" && extension !== "mcworld" && extension !== "mctemplate") {
return undefined;
}
if (!containerFile.fileContainerStorage) {
const zipStorage = new ZipStorage_1.default();
if (!containerFile.isContentLoaded) {
await containerFile.loadContent();
}
if (!containerFile.content || !(containerFile.content instanceof Uint8Array)) {
return undefined;
}
await zipStorage.loadFromUint8Array(containerFile.content);
zipStorage.containerFile = containerFile;
containerFile.fileContainerStorage = zipStorage;
containerFile.fileContainerStorage.storagePath = containerFilePath + "#";
}
targetFolder = containerFile.fileContainerStorage.rootFolder;
}
await targetFolder.ensureFolderFromRelativePath(basePath);
await targetFolder.ensureExists();
candidateFilePath = basePath + baseName + "." + extension;
candidateFile = await targetFolder.getFileFromRelativePath(candidateFilePath);
if (candidateFile) {
// find a filename not in use
do {
index++;
candidateFilePath = basePath + baseName + index + "." + extension;
candidateFile = await targetFolder.getFileFromRelativePath(candidateFilePath);
} while (candidateFile !== null && candidateFile !== undefined);
}
return finalPathPrefix + candidateFilePath;
}
static async createNewGameTestScript(project) {
const defaultPath = await ProjectItemCreateManager._getDefaultBehaviorPackFolderPath(project, "scripts");
if (defaultPath === undefined) {
return;
}
const candidateFilePath = await ProjectItemCreateManager._generateFileNameForNewItem(project, defaultPath, "test", "js");
if (candidateFilePath === undefined) {
return;
}
const pi = project.ensureItemByProjectPath(candidateFilePath, IProjectItemData_1.ProjectItemStorageType.singleFile, StorageUtilities_1.default.getLeafName(candidateFilePath), IProjectItemData_1.ProjectItemType.testJs, Project_1.FolderContext.behaviorPack, undefined, IProjectItemData_1.ProjectItemCreationType.normal);
const file = await pi.loadFileContent();
if (file !== null) {
const baseName = StorageUtilities_1.default.getBaseFromName(file.name);
if (project.preferredScriptLanguage === IProjectData_1.ProjectScriptLanguage.typeScript) {
const tsFile = file.parentFolder.ensureFile(baseName + ".ts");
if (tsFile !== null) {
const content = ProjectContent_1.default.getEmptyTestTypeScript(project.name, baseName);
tsFile.setContent(content);
}
}
const content = ProjectContent_1.default.getEmptyTestJavaScript(project.name, baseName);
file.setContent(content);
}
await project.save();
}
static async createNewFunction(project) {
const defaultPath = await this._getDefaultBehaviorPackFolderPath(project, "functions");
if (defaultPath === undefined) {
return;
}
const candidateFilePath = await ProjectItemCreateManager._generateFileNameForNewItem(project, defaultPath, "action", "mcfunction");
if (candidateFilePath === undefined) {
return;
}
const pi = project.ensureItemByProjectPath(candidateFilePath, IProjectItemData_1.ProjectItemStorageType.singleFile, StorageUtilities_1.default.getLeafName(candidateFilePath), IProjectItemData_1.ProjectItemType.MCFunction, Project_1.FolderContext.behaviorPack, undefined, IProjectItemData_1.ProjectItemCreationType.normal);
const file = await pi.loadFileContent();
if (file !== null) {
const content = "say hello";
file.setContent(content);
}
await project.save();
}
static async createNewStructure(project) {
const defaultPath = await ProjectItemCreateManager._getDefaultBehaviorPackFolderPath(project, "structures");
if (defaultPath === undefined) {
return;
}
const candidateFilePath = await ProjectItemCreateManager._generateFileNameForNewItem(project, defaultPath, "structure", "mcstructure");
if (candidateFilePath === undefined) {
return;
}
const pi = project.ensureItemByProjectPath(candidateFilePath, IProjectItemData_1.ProjectItemStorageType.singleFile, StorageUtilities_1.default.getLeafName(candidateFilePath), IProjectItemData_1.ProjectItemType.structure, Project_1.FolderContext.behaviorPack, undefined, IProjectItemData_1.ProjectItemCreationType.normal);
const file = await pi.loadFileContent();
if (file !== null) {
const structureBytes = ProjectContent_1.default.generateDefaultStructure();
if (structureBytes !== undefined) {
file.setContent(structureBytes);
}
}
await project.save();
}
/**
* "Empty file" / "Open as Raw" companion: drops a minimally-valid stub at the
* conventional sub-folder for `contentType` under the project's default
* behavior or resource pack. Used by the Add dialog's "Empty File (advanced)"
* path so power users can author files that don't fit an existing wizard.
*
* If `desiredName` is omitted or already taken, a numeric suffix is appended
* (handled by `_generateFileNameForNewItem`). Returns the created
* `ProjectItem` so callers can select/open it.
*/
static async createNewEmptyStubFile(project, contentType, desiredName) {
const config = ProjectItemCreateManager._getEmptyStubConfig(contentType);
if (!config) {
Log_1.default.error("createNewEmptyStubFile: unsupported contentType " + contentType);
return undefined;
}
const baseFileName = (desiredName && desiredName.trim()) || config.defaultBaseName;
let defaultPath;
if (config.folderContext === Project_1.FolderContext.resourcePack) {
defaultPath = await ProjectItemCreateManager._getDefaultResourcePackFolderPath(project, config.subfolder);
}
else {
defaultPath = await ProjectItemCreateManager._getDefaultBehaviorPackFolderPath(project, config.subfolder);
}
if (defaultPath === undefined) {
return undefined;
}
const candidateFilePath = await ProjectItemCreateManager._generateFileNameForNewItem(project, defaultPath, baseFileName, config.extension);
if (candidateFilePath === undefined) {
return undefined;
}
const pi = project.ensureItemByProjectPath(candidateFilePath, IProjectItemData_1.ProjectItemStorageType.singleFile, StorageUtilities_1.default.getLeafName(candidateFilePath), contentType, config.folderContext, undefined, IProjectItemData_1.ProjectItemCreationType.normal);
const file = await pi.loadFileContent();
if (file !== null && config.stubContent !== undefined) {
file.setContent(config.stubContent);
}
await project.save();
return pi;
}
/**
* Map a content type to the sub-folder, default file name, extension, and
* minimally-valid stub content used by `createNewEmptyStubFile`. Stubs are
* intentionally tiny — the goal is to land an editable file at the right
* path, not to template a fully-valid definition (the wizards do that).
*
* TODO: the `format_version` in JSON stubs is hardcoded to `STUB_FORMAT_VERSION`
* below. The rest of the codebase resolves the latest format version
* dynamically (see `FormatVersionManager` and `Database.getLatestVersionInfo`).
* When this method becomes async-friendly, pull the version from there so
* stubs don't go stale.
*/
static STUB_FORMAT_VERSION = "1.21.0";
// Lazily built on first access. Building this eagerly via a static IIFE caused
// a "Cannot read properties of undefined (reading 'behaviorPack')" crash at
// module load when this file ended up earlier in a circular import chain than
// ./Project (which exports FolderContext).
static _emptyStubConfigsCache;
static get EMPTY_STUB_CONFIGS() {
if (ProjectItemCreateManager._emptyStubConfigsCache) {
return ProjectItemCreateManager._emptyStubConfigsCache;
}
const v = ProjectItemCreateManager.STUB_FORMAT_VERSION;
const json = (body) => body;
const bp = Project_1.FolderContext.behaviorPack;
ProjectItemCreateManager._emptyStubConfigsCache = {
[IProjectItemData_1.ProjectItemType.entityTypeBehavior]: {
subfolder: "entities",
defaultBaseName: "entity",
extension: "json",
folderContext: bp,
body: json(`{\n "format_version": "${v}",\n "minecraft:entity": {\n "description": {},\n "components": {}\n }\n}\n`),
},
[IProjectItemData_1.ProjectItemType.blockTypeBehavior]: {
subfolder: "blocks",
defaultBaseName: "block",
extension: "json",
folderContext: bp,
body: json(`{\n "format_version": "${v}",\n "minecraft:block": {\n "description": {},\n "components": {}\n }\n}\n`),
},
[IProjectItemData_1.ProjectItemType.itemTypeBehavior]: {
subfolder: "items",
defaultBaseName: "item",
extension: "json",
folderContext: bp,
body: json(`{\n "format_version": "${v}",\n "minecraft:item": {\n "description": {},\n "components": {}\n }\n}\n`),
},
[IProjectItemData_1.ProjectItemType.lootTableBehavior]: {
subfolder: "loot_tables",
defaultBaseName: "loot_table",
extension: "json",
folderContext: bp,
body: '{\n "pools": []\n}\n',
},
[IProjectItemData_1.ProjectItemType.recipeBehavior]: {
subfolder: "recipes",
defaultBaseName: "recipe",
extension: "json",
folderContext: bp,
body: json(`{\n "format_version": "${v}",\n "minecraft:recipe_shapeless": {\n "description": {},\n "tags": [],\n "ingredients": [],\n "result": {}\n }\n}\n`),
},
[IProjectItemData_1.ProjectItemType.spawnRuleBehavior]: {
subfolder: "spawn_rules",
defaultBaseName: "spawn_rule",
extension: "json",
folderContext: bp,
body: json(`{\n "format_version": "${v}",\n "minecraft:spawn_rules": {\n "description": {},\n "conditions": []\n }\n}\n`),
},
[IProjectItemData_1.ProjectItemType.MCFunction]: {
subfolder: "functions",
defaultBaseName: "action",
extension: "mcfunction",
folderContext: bp,
body: "# New function — add commands below\n",
},
[IProjectItemData_1.ProjectItemType.unknownJson]: {
subfolder: "",
defaultBaseName: "untitled",
extension: "json",
folderContext: bp,
body: "{}\n",
},
};
return ProjectItemCreateManager._emptyStubConfigsCache;
}
static _getEmptyStubConfig(contentType) {
const entry = ProjectItemCreateManager.EMPTY_STUB_CONFIGS[contentType];
if (!entry) {
return undefined;
}
return {
subfolder: entry.subfolder,
defaultBaseName: entry.defaultBaseName,
extension: entry.extension,
folderContext: entry.folderContext,
stubContent: entry.body,
};
}
static async createNewActionSet(project) {
const defaultPath = await this._getDefaultBehaviorPackFolderPath(project, "actions");
if (defaultPath === undefined) {
return;
}
const candidateFilePath = await ProjectItemCreateManager._generateFileNameForNewItem(project, defaultPath, "actionset", "json");
if (candidateFilePath === undefined) {
return;
}
const pi = project.ensureItemByProjectPath(candidateFilePath, IProjectItemData_1.ProjectItemStorageType.singleFile, StorageUtilities_1.default.getLeafName(candidateFilePath), IProjectItemData_1.ProjectItemType.actionSet, Project_1.FolderContext.behaviorPack, undefined, IProjectItemData_1.ProjectItemCreationType.normal);
const file = await pi.loadFileContent();
if (file !== null) {
const baseName = StorageUtilities_1.default.getBaseFromName(file.name);
const content = ProjectContent_1.default.getEmptyActionSet(project.name, baseName);
file.setContent(content);
}
await ProjectAutogeneration_1.default.updateProjectAutogeneration(project, false);
}
static async createNewDocumentedType(project) {
const defaultPath = await this._getDefaultBehaviorPackFolderPath(project, "docs");
if (defaultPath === undefined) {
return;
}
const candidateFolderPath = await ProjectItemCreateManager._generateFolderNameForNewItem(project, defaultPath, "type");
if (candidateFolderPath === undefined) {
return;
}
const pi = project.ensureItemByProjectPath(candidateFolderPath, IProjectItemData_1.ProjectItemStorageType.folder, candidateFolderPath, IProjectItemData_1.ProjectItemType.documentedTypeFolder, Project_1.FolderContext.metaData, undefined, IProjectItemData_1.ProjectItemCreationType.normal);
await pi.loadFolder();
await ProjectAutogeneration_1.default.updateProjectAutogeneration(project, false);
await project.save();
}
static getExistingPath(project, itemType) {
if (!project.projectFolder) {
return undefined;
}
for (const item of project.items) {
if (item.itemType === itemType && item.primaryFile) {
return item.primaryFile.parentFolder.getFolderRelativePath(project.projectFolder);
}
}
return undefined;
}
static async createNewForm(project, name, folder) {
let path = undefined;
if (!project.projectFolder) {
return undefined;
}
if (folder) {
path = folder.getFolderRelativePath(project.projectFolder);
}
else {
path = ProjectItemCreateManager.getExistingPath(project, IProjectItemData_1.ProjectItemType.dataForm);
if (path === undefined) {
path = await this._getDefaultBehaviorPackFolderPath(project, "forms");
if (path === undefined) {
return undefined;
}
}
}
if (!path) {
return undefined;
}
if (!name) {
name = "form";
}
const candidateFilePath = await ProjectItemCreateManager._generateFileNameForNewItem(project, path, name, "form.json");
if (candidateFilePath === undefined) {
return undefined;
}
const pi = project.ensureItemByProjectPath(candidateFilePath, IProjectItemData_1.ProjectItemStorageType.singleFile, StorageUtilities_1.default.getLeafName(candidateFilePath), IProjectItemData_1.ProjectItemType.dataForm, Project_1.FolderContext.metaData, undefined, IProjectItemData_1.ProjectItemCreationType.normal);
const file = await pi.loadFileContent();
if (file !== null) {
const content = "{}";
file.setContent(content);
}
await ProjectAutogeneration_1.default.updateProjectAutogeneration(project, false);
await project.save();
return pi;
}
static async ensureSoundDefinitionCatalogDefinition(project) {
const items = project.getItemsByType(IProjectItemData_1.ProjectItemType.soundDefinitionCatalog);
if (items.length > 0) {
if (!items[0].isContentLoaded) {
await items[0].loadContent();
}
const itemFile = items[0].primaryFile;
if (itemFile) {
if (!itemFile.isContentLoaded) {
await itemFile.loadContent();
}
if (!itemFile.content) {
this.setFileToDefaultContent(itemFile);
}
return await SoundDefinitionCatalogDefinition_1.default.ensureOnFile(itemFile);
}
}
let path = undefined;
if (!project.projectFolder) {
return undefined;
}
path = await this._getDefaultResourcePackFolderPath(project, "sounds");
if (path === undefined) {
return undefined;
}
const candidateFilePath = await ProjectItemCreateManager._generateFileNameForNewItem(project, path, "sound_definitions", "json");
if (candidateFilePath === undefined) {
return undefined;
}
const pi = project.ensureItemByProjectPath(candidateFilePath, IProjectItemData_1.ProjectItemStorageType.singleFile, StorageUtilities_1.default.getLeafName(candidateFilePath), IProjectItemData_1.ProjectItemType.soundDefinitionCatalog, Project_1.FolderContext.resourcePack, undefined, IProjectItemData_1.ProjectItemCreationType.normal);
const file = await pi.loadFileContent();
if (file === null) {
return undefined;
}
this.setFileToDefaultContent(file);
await ProjectAutogeneration_1.default.updateProjectAutogeneration(project, false);
await project.save();
return await SoundDefinitionCatalogDefinition_1.default.ensureOnFile(file);
}
static setFileToDefaultContent(file) {
const content = '{\n "format_version" : "1.20.20",\n "sound_definitions" : {}\n}';
file.setContent(content);
file.saveContent();
}
static async addFromGallery(project, newName, galleryItem) {
if (galleryItem.type === IGalleryItem_1.GalleryItemType.entityType) {
await ProjectCreateManager_1.default.addEntityTypeFromGallery(project, galleryItem, newName, ProjectUtilities_1.NewEntityTypeAddMode.baseId, async (message) => {
Log_1.default.message(message);
});
}
else if (galleryItem.type === IGalleryItem_1.GalleryItemType.itemType) {
await ProjectCreateManager_1.default.addItemTypeFromGallery(project, galleryItem, newName);
}
else if (galleryItem.type === IGalleryItem_1.GalleryItemType.blockType) {
await ProjectCreateManager_1.default.addBlockTypeFromGallery(project, galleryItem, newName);
}
else if (galleryItem.type === IGalleryItem_1.GalleryItemType.modelDesign) {
await ProjectCreateManager_1.default.addModelDesignFromGallery(project, galleryItem, newName);
}
else if (galleryItem.type >= IGalleryItem_1.GalleryItemType.spawnLootRecipes && galleryItem.targetType) {
await ProjectItemCreateManager.createNewItem(project, {
itemType: galleryItem.targetType,
contentTemplateName: galleryItem.id,
name: newName,
folder: undefined,
});
}
}
static async ensureSoundCatalogDefinition(project) {
const items = project.getItemsByType(IProjectItemData_1.ProjectItemType.soundCatalog);
if (items.length > 0) {
if (!items[0].isContentLoaded) {
await items[0].loadContent();
}
if (items[0].primaryFile) {
return await SoundCatalogDefinition_1.default.ensureOnFile(items[0].primaryFile);
}
}
let path = undefined;
if (!project.projectFolder) {
return undefined;
}
path = await this._getDefaultResourcePackFolderPath(project, "sounds");
if (path === undefined) {
return undefined;
}
const candidateFilePath = await ProjectItemCreateManager._generateFileNameForNewItem(project, path, "sounds", "json");
if (candidateFilePath === undefined) {
return undefined;
}
const pi = project.ensureItemByProjectPath(candidateFilePath, IProjectItemData_1.ProjectItemStorageType.singleFile, StorageUtilities_1.default.getLeafName(candidateFilePath), IProjectItemData_1.ProjectItemType.soundCatalog, Project_1.FolderContext.resourcePack, undefined, IProjectItemData_1.ProjectItemCreationType.normal);
const file = await pi.loadFileContent();
if (file === null) {
return undefined;
}
const content = "{\n}";
file.setContent(content);
await ProjectAutogeneration_1.default.updateProjectAutogeneration(project, false);
await project.save();
return await SoundCatalogDefinition_1.default.ensureOnFile(file);
}
static async createDesignPackJsonItem(project, itemSeed) {
let path = undefined;
if (!project.projectFolder) {
return undefined;
}
const folderRootsForType = ProjectItemUtilities_1.default.getFolderRootsForType(itemSeed.itemType);
Log_1.default.assert(folderRootsForType.length > 0, "No folder roots for item type: " + itemSeed.itemType);
if (itemSeed.folder) {
path = itemSeed.folder.getFolderRelativePath(project.projectFolder);
}
else {
path = ProjectItemCreateManager.getExistingPath(project, itemSeed.itemType);
if (path === undefined) {
path = await this._getDefaultDesignPackFolderPath(project, folderRootsForType[0]);
if (path === undefined) {
return undefined;
}
}
}
if (!path) {
return undefined;
}
let namespacedId = itemSeed.name;
let name = namespacedId;
if (!namespacedId || !name) {
name = ProjectItemUtilities_1.default.getNewItemTechnicalName(itemSeed.itemType);
namespacedId = name;
}
name = MinecraftUtilities_1.default.getNamespacedIdName(name);
const candidateFilePath = await ProjectItemCreateManager._generateFileNameForNewItem(project, path, name, "json");
if (candidateFilePath === undefined) {
return undefined;
}
const pi = project.ensureItemByProjectPath(candidateFilePath, IProjectItemData_1.ProjectItemStorageType.singleFile, StorageUtilities_1.default.getLeafName(candidateFilePath), itemSeed.itemType, Project_1.FolderContext.designPack, undefined, IProjectItemData_1.ProjectItemCreationType.normal);
const file = await pi.loadFileContent();
if (file !== null) {
let content = "{}";
await Database_1.default.loadContent();
if (Database_1.default.contentFolder !== null) {
const contentTemplate = itemSeed.contentTemplateName
? itemSeed.contentTemplateName
: ProjectItemUtilities_1.default.getNewItemTechnicalName(itemSeed.itemType);
const sourceFile = await Database_1.default.contentFolder.getFileFromRelativePath("/newitemjson/" + contentTemplate + ".json");
if (sourceFile) {
if (!sourceFile.isContentLoaded) {
await sourceFile.loadContent();
}
if (sourceFile.content) {
content = sourceFile.content.toString();
}
}
}
content = content.replace(/examplens:examplename/g, namespacedId);
file.setContent(content);
}
await ProjectAutogeneration_1.default.updateProjectAutogeneration(project, false);
await project.save();
return pi;
}
static async createBehaviorPackJsonItem(project, itemSeed) {
let path = undefined;
if (!project.projectFolder) {
return undefined;
}
const folderRootsForType = ProjectItemUtilities_1.default.getFolderRootsForType(itemSeed.itemType);
Log_1.default.assert(folderRootsForType.length > 0, "No folder roots for item type: " + itemSeed.itemType);
if (itemSeed.folder) {
path = itemSeed.folder.getFolderRelativePath(project.projectFolder);
}
else {
path = ProjectItemCreateManager.getExistingPath(project, itemSeed.itemType);
if (path === undefined) {
path = await this._getDefaultBehaviorPackFolderPath(project, folderRootsForType[0]);
if (path === undefined) {
return undefined;
}
}
}
if (!path) {
return undefined;
}
let namespacedId = itemSeed.name;
let name = namespacedId;
if (!namespacedId || !name) {
name = ProjectItemUtilities_1.default.getNewItemTechnicalName(itemSeed.itemType);
namespacedId = name;
}
name = MinecraftUtilities_1.default.getNamespacedIdName(name);
const candidateFilePath = await ProjectItemCreateManager._generateFileNameForNewItem(project, path, name, "json");
if (candidateFilePath === undefined) {
return undefined;
}
const pi = project.ensureItemByProjectPath(candidateFilePath, IProjectItemData_1.ProjectItemStorageType.singleFile, StorageUtilities_1.default.getLeafName(candidateFilePath), itemSeed.itemType, Project_1.FolderContext.behaviorPack, undefined, IProjectItemData_1.ProjectItemCreationType.normal);
const file = await pi.loadFileContent();
if (file !== null) {
let content = "{}";
await Database_1.default.loadContent();
if (Database_1.default.contentFolder !== null) {
const contentTemplate = itemSeed.contentTemplateName
? itemSeed.contentTemplateName
: ProjectItemUtilities_1.default.getNewItemTechnicalName(itemSeed.itemType);
const path = "/newitemjson/" + contentTemplate + ".json";
const sourceFile = await Database_1.default.contentFolder.getFileFromRelativePath(path);
if (sourceFile) {
if (!sourceFile.isContentLoaded) {
await sourceFile.loadContent();
}
if (sourceFile.content) {
content = sourceFile.content.toString();
}
}
}
content = content.replace(/examplens:examplename/g, namespacedId);
file.setContent(content);
}
await ProjectAutogeneration_1.default.updateProjectAutogeneration(project, false);
await project.save();
return pi;
}
static async createResourcePackJsonItem(project, itemSeed) {
let path = undefined;
if (!project.projectFolder) {
return undefined;
}
const folderRootsForType = ProjectItemUtilities_1.default.getFolderRootsForType(itemSeed.itemType);
Log_1.default.assert(folderRootsForType.length > 0, "No folder roots for item type: " + itemSeed.itemType);
if (itemSeed.folder) {
path = itemSeed.folder.getFolderRelativePath(project.projectFolder);
}
else {
path = ProjectItemCreateManager.getExistingPath(project, itemSeed.itemType);
if (path === undefined) {
path = await this._getDefaultResourcePackFolderPath(project, folderRootsForType[0]);
if (path === undefined) {
return undefined;
}
}
}
if (!path) {
return undefined;
}
let namespacedId = itemSeed.name;
let name = namespacedId;
if (!namespacedId || !name) {
name = ProjectItemUtilities_1.default.getNewItemTechnicalName(itemSeed.itemType);
namespacedId = name;
}
name = MinecraftUtilities_1.default.getNamespacedIdName(name);
const candidateFilePath = await ProjectItemCreateManager._generateFileNameForNewItem(project, path, name, "json");
if (candidateFilePath === undefined) {
return undefined;
}
const pi = project.ensureItemByProjectPath(candidateFilePath, IProjectItemData_1.ProjectItemStorageType.singleFile, StorageUtilities_1.default.getLeafName(candidateFilePath), itemSeed.itemType, Project_1.FolderContext.resourcePack, undefined, IProjectItemData_1.ProjectItemCreationType.normal);
const file = await pi.loadFileContent();
if (file !== null) {
let content = "{}";
await Database_1.default.loadContent();
if (Database_1.default.contentFolder !== null) {
const contentTemplate = itemSeed.contentTemplateName
? itemSeed.contentTemplateName
: ProjectItemUtilities_1.default.getNewItemTechnicalName(itemSeed.itemType);
const sourceFile = await Database_1.default.contentFolder.getFileFromRelativePath("/newitemjson/" + contentTemplate + ".json");
if (sourceFile) {
if (!sourceFile.isContentLoaded) {
await sourceFile.loadContent();
}
if (sourceFile.content) {
content = sourceFile.content.toString();
}
}
}
content = content.replace(/examplens:examplename/g, namespacedId);
file.setContent(content);
}
await ProjectAutogeneration_1.default.updateProjectAutogeneration(project, false);
await project.save();
return pi;
}
static async createNewResourcePackBinaryItem(project, sourceFileName, extension, defaultFolderPath, exampleName, itemType, name, folder) {
let path = undefined;
if (!project.projectFolder) {
return undefined;
}
await Database_1.default.loadContent();
if (Database_1.default.contentFolder === null) {
Log_1.default.unexpectedContentState();
return undefined;
}
const sourceFile = Database_1.default.contentFolder.ensureFile(sourceFileName);
if (!sourceFile.isContentLoaded) {
await sourceFile.loadContent();
}
if (!(sourceFile.content instanceof Uint8Array)) {
Log_1.default.error("Could not find source " + extension + " file content.");
return;
}
if (folder) {
path = folder.getFolderRelativePath(project.projectFolder);
}
else {
path = ProjectItemCreateManager.getExistingPath(project, itemType);
if (path === undefined) {
path = await this._getDefaultResourcePackFolderPath(project, defaultFolderPath);
if (path === undefined) {
return undefined;
}
}
}
if (!path) {
return undefined;
}
if (!name) {
name = exampleName;
}
const candidateFilePath = await ProjectItemCreateManager._generateFileNameForNewItem(project, path, name, extension);
if (candidateFilePath === undefined) {
return undefined;
}
const pi = project.ensureItemByProjectPath(candidateFilePath, IProjectItemData_1.ProjectItemStorageType.singleFile, StorageUtilities_1.default.getLeafName(candidateFilePath), itemType, Project_1.FolderContext.resourcePack, undefined, IProjectItemData_1.ProjectItemCreationType.normal);
const file = await pi.loadFileContent();
if (file !== null) {
file.setContent(sourceFile.content);
}
await ProjectAutogeneration_1.default.updateProjectAutogeneration(project, false);
await project.save();
return pi;
}
static async createNewDesignPackBinaryItem(project, sourceFileName, extension, defaultFolderPath, exampleName, itemType, name, folder) {
let path = undefined;
if (!project.projectFolder) {
return undefined;
}
await Database_1.default.loadContent();
if (Database_1.default.contentFolder === null) {
Log_1.default.unexpectedContentState();
return undefined;
}
const sourceFile = Database_1.default.contentFolder.ensureFile(sourceFileName);
if (!sourceFile.isContentLoaded) {
await sourceFile.loadContent();
}
if (!(sourceFile.content instanceof Uint8Array)) {
Log_1.default.error("Could not find source " + extension + " file content.");
return;
}
if (folder) {
path = folder.getFolderRelativePath(project.projectFolder);
}
else {
path = ProjectItemCreateManager.getExistingPath(project, itemType);
if (path === undefined) {
path = await this._getDefaultDesignPackFolderPath(project, defaultFolderPath);
if (path === undefined) {
return undefined;
}
}
}
if (!path) {
return undefined;
}
if (!name) {
name = exampleName;
}
const candidateFilePath = await ProjectItemCreateManager._generateFileNameForNewItem(project, path, name, extension);
if (candidateFilePath === undefined) {
return undefined;
}
const pi = project.ensureItemByProjectPath(candidateFilePath, IProjectItemData_1.ProjectItemStorageType.singleFile, StorageUtilities_1.default.getLeafName(candidateFilePath), itemType, Project_1.FolderContext.designPack, undefined, IProjectItemData_1.ProjectItemCreationType.normal);
const file = await pi.loadFileContent();
if (file !== null) {
file.setContent(sourceFile.content);
}
await ProjectAutogeneration_1.default.updateProjectAutogeneration(project, false);
await project.save();
return pi;
}
static async createNewDesignTexture(project, name, folder, creationData) {
const projectItem = await this.createNewDesignPackBinaryItem(project, "blank64.png", "png", "design_textures", "design_texture", IProjectItemData_1.ProjectItemType.designTexture, name, folder);
if (projectItem && creationData) {
const imageEdits = await ImageEditsDefinition_1.default.ensureAsAccessoryOnImageProjectItem(projectItem);
if (imageEdits) {
await imageEdits.setFromCreationData(creationData);
}
}
return projectItem;
}
static async createNewTexture(project, name, folder) {
return await this.createNewResourcePackBinaryItem(project, "blank64.png", "png", "textures", "texture", IProjectItemData_1.ProjectItemType.texture, name, folder);
}
static async createNewAudio(project, name, folder) {
return await this.createNewResourcePackBinaryItem(project, "blank.ogg", "ogg", "sounds", "sound", IProjectItemData_1.ProjectItemType.audio, name, folder);
}
static async createNewWorldTest(project, name, folder) {
let path = undefined;
if (!project.projectFolder) {
return;
}
if (folder) {
path = folder.getFolderRelativePath(project.projectFolder);
}
else {
path = ProjectItemCreateManager.getExistingPath(project, IProjectItemData_1.ProjectItemType.dataForm);
if (path === undefined) {
path = await this._getDefaultBehaviorPackFolderPath(project, "forms");
if (path === undefined) {
return;
}
}
}
if (!path) {
return;
}
if (!name) {
name = "form";
}
const candidateFilePath = await ProjectItemCreateManager._generateFileNameForNewItem(project, path + "tests/", "worldtest", "json");
if (candidateFilePath === undefined) {
return;
}
const pi = project.ensureItemByProjectPath(candidateFilePath, IProjectItemData_1.ProjectItemStorageType.singleFile, StorageUtilities_1.default.getLeafName(candidateFilePath), IProjectItemData_1.ProjectItemType.worldTest, Project_1.FolderContext.behaviorPack, undefined, IProjectItemData_1.ProjectItemCreationType.normal);
const file = await pi.loadFileContent();
if (file !== null) {
const baseName = StorageUtilities_1.default.getBaseFromName(file.name);
const content = ProjectContent_1.default.getEmptyWorldTest(project.name, baseName);
file.setContent(content);
}
await ProjectAutogeneration_1.default.updateProjectAutogeneration(project, false);
await project.save();
}
}
exports.default = ProjectItemCreateManager;