UNPKG

@minecraft/creator-tools

Version:

Minecraft Creator Tools command line and libraries.

550 lines (548 loc) 26.9 kB
"use strict"; // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. Object.defineProperty(exports, "__esModule", { value: true }); const ProjectContent_1 = require("./ProjectContent"); const IProjectData_1 = require("./IProjectData"); const IProjectItemData_1 = require("./IProjectItemData"); const StorageUtilities_1 = require("./../storage/StorageUtilities"); const ZipStorage_1 = require("../storage/ZipStorage"); const ProjectItemUtilities_1 = require("./ProjectItemUtilities"); const ProjectAutogeneration_1 = require("./ProjectAutogeneration"); const Database_1 = require("../minecraft/Database"); const Log_1 = require("../core/Log"); const SoundDefinitionCatalogDefinition_1 = require("../minecraft/SoundDefinitionCatalogDefinition"); const SoundCatalogDefinition_1 = require("../minecraft/SoundCatalogDefinition"); class ProjectItemManager { 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 _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); } if (itemSeed.itemType) { switch (itemSeed.itemType) { case IProjectItemData_1.ProjectItemType.js: case IProjectItemData_1.ProjectItemType.ts: return ProjectItemManager.createNewScript(project, itemSeed.itemType, itemSeed.name, itemSeed.folder); case IProjectItemData_1.ProjectItemType.dataForm: return ProjectItemManager.createNewForm(project, itemSeed.name, itemSeed.folder); case IProjectItemData_1.ProjectItemType.spawnRuleBehavior: return ProjectItemManager.createNewSpawnRule(project, itemSeed.name, itemSeed.folder); case IProjectItemData_1.ProjectItemType.audio: return ProjectItemManager.createNewAudio(project, itemSeed.name, itemSeed.folder); } } return undefined; } static async createNewScript(project, itemType, name, folder) { let defaultPath = undefined; if (folder && project.projectFolder) { defaultPath = folder.getFolderRelativePath(project.projectFolder); } else { defaultPath = await ProjectItemManager._getDefaultScriptsFolderPath(project); } if (defaultPath === undefined) { return; } const candidateFilePath = await ProjectItemManager._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, undefined, IProjectItemData_1.ProjectItemCreationType.normal); const file = await pi.ensureFileStorage(); 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); 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(); await containerFile.loadContent(); if (!containerFile.content || !(containerFile.content instanceof Uint8Array)) { return undefined; } await zipStorage.loadFromUint8Array(containerFile.content, containerFile.name); 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(); await containerFile.loadContent(); if (!containerFile.content || !(containerFile.content instanceof Uint8Array)) { return undefined; } await zipStorage.loadFromUint8Array(containerFile.content); 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 ProjectItemManager._getDefaultBehaviorPackFolderPath(project, "scripts"); if (defaultPath === undefined) { return; } const candidateFilePath = await ProjectItemManager._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, undefined, IProjectItemData_1.ProjectItemCreationType.normal); const file = await pi.ensureFileStorage(); 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 ProjectItemManager._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, undefined, IProjectItemData_1.ProjectItemCreationType.normal); const file = await pi.ensureFileStorage(); if (file !== null) { const content = "say hello"; file.setContent(content); } await project.save(); } static async createNewStructure(project) { const defaultPath = await ProjectItemManager._getDefaultBehaviorPackFolderPath(project, "structures"); if (defaultPath === undefined) { return; } const candidateFilePath = await ProjectItemManager._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, undefined, IProjectItemData_1.ProjectItemCreationType.normal); const file = await pi.ensureFileStorage(); if (file !== null) { const structureBytes = ProjectContent_1.default.generateDefaultStructure(); if (structureBytes !== undefined) { file.setContent(structureBytes); } } await project.save(); } static async createNewActionSet(project) { const defaultPath = await this._getDefaultBehaviorPackFolderPath(project, "actions"); if (defaultPath === undefined) { return; } const candidateFilePath = await ProjectItemManager._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, undefined, IProjectItemData_1.ProjectItemCreationType.normal); const file = await pi.ensureFileStorage(); 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); } static async createNewDocumentedType(project) { const defaultPath = await this._getDefaultBehaviorPackFolderPath(project, "docs"); if (defaultPath === undefined) { return; } const candidateFolderPath = await ProjectItemManager._generateFolderNameForNewItem(project, defaultPath, "type"); if (candidateFolderPath === undefined) { return; } const pi = project.ensureItemByProjectPath(candidateFolderPath, IProjectItemData_1.ProjectItemStorageType.folder, candidateFolderPath, IProjectItemData_1.ProjectItemType.documentedTypeFolder, undefined, IProjectItemData_1.ProjectItemCreationType.normal); await pi.ensureFolderStorage(); await ProjectAutogeneration_1.default.updateProjectAutogeneration(project); await project.save(); } static getExistingPath(project, itemType) { if (!project.projectFolder) { return undefined; } for (const item of project.items) { if (item.itemType === itemType && item.file) { return item.file.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 = ProjectItemManager.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 ProjectItemManager._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, undefined, IProjectItemData_1.ProjectItemCreationType.normal); const file = await pi.ensureFileStorage(); if (file !== null) { const content = "{}"; file.setContent(content); } await ProjectAutogeneration_1.default.updateProjectAutogeneration(project); await project.save(); return pi; } static async ensureSoundDefinitionCatalogDefinition(project) { const items = project.getItemByType(IProjectItemData_1.ProjectItemType.soundDefinitionCatalog); if (items.length > 0) { await items[0].ensureStorage(); if (items[0].file) { await items[0].file.loadContent(); if (!items[0].file.content) { this.setFileToDefaultContent(items[0].file); } return await SoundDefinitionCatalogDefinition_1.default.ensureOnFile(items[0].file); } } let path = undefined; if (!project.projectFolder) { return undefined; } path = await this._getDefaultResourcePackFolderPath(project, "sounds"); if (path === undefined) { return undefined; } const candidateFilePath = await ProjectItemManager._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, undefined, IProjectItemData_1.ProjectItemCreationType.normal); const file = await pi.ensureFileStorage(); if (file === null) { return undefined; } this.setFileToDefaultContent(file); await ProjectAutogeneration_1.default.updateProjectAutogeneration(project); await project.save(); return await SoundDefinitionCatalogDefinition_1.default.ensureOnFile(file); } static setFileToDefaultContent(file) { const content = '{\r\n "format_version" : "1.20.20",\r\n "sound_definitions" : {}\r\n}'; file.setContent(content); file.saveContent(); } static async ensureSoundCatalogDefinition(project) { const items = project.getItemByType(IProjectItemData_1.ProjectItemType.soundCatalog); if (items.length > 0) { await items[0].ensureStorage(); if (items[0].file) { return await SoundCatalogDefinition_1.default.ensureOnFile(items[0].file); } } let path = undefined; if (!project.projectFolder) { return undefined; } path = await this._getDefaultResourcePackFolderPath(project, "sounds"); if (path === undefined) { return undefined; } const candidateFilePath = await ProjectItemManager._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, undefined, IProjectItemData_1.ProjectItemCreationType.normal); const file = await pi.ensureFileStorage(); if (file === null) { return undefined; } const content = "{\r\n}"; file.setContent(content); await ProjectAutogeneration_1.default.updateProjectAutogeneration(project); await project.save(); return await SoundCatalogDefinition_1.default.ensureOnFile(file); } static async createNewSpawnRule(project, name, folder) { let path = undefined; if (!project.projectFolder) { return undefined; } if (folder) { path = folder.getFolderRelativePath(project.projectFolder); } else { path = ProjectItemManager.getExistingPath(project, IProjectItemData_1.ProjectItemType.spawnRuleBehavior); if (path === undefined) { path = await this._getDefaultBehaviorPackFolderPath(project, "spawn_rules"); if (path === undefined) { return undefined; } } } if (!path) { return undefined; } if (!name) { name = "spawn_rule"; } const candidateFilePath = await ProjectItemManager._generateFileNameForNewItem(project, path, name, "json"); if (candidateFilePath === undefined) { return undefined; } const pi = project.ensureItemByProjectPath(candidateFilePath, IProjectItemData_1.ProjectItemStorageType.singleFile, StorageUtilities_1.default.getLeafName(candidateFilePath), IProjectItemData_1.ProjectItemType.spawnRuleBehavior, undefined, IProjectItemData_1.ProjectItemCreationType.normal); const file = await pi.ensureFileStorage(); if (file !== null) { const content = "{}"; file.setContent(content); } await ProjectAutogeneration_1.default.updateProjectAutogeneration(project); await project.save(); return pi; } static async createNewAudio(project, 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("blank.ogg"); await sourceFile.loadContent(); if (!(sourceFile.content instanceof Uint8Array)) { Log_1.default.error("Could not find source OGG file content."); return; } if (folder) { path = folder.getFolderRelativePath(project.projectFolder); } else { path = ProjectItemManager.getExistingPath(project, IProjectItemData_1.ProjectItemType.audio); if (path === undefined) { path = await this._getDefaultResourcePackFolderPath(project, "sounds"); if (path === undefined) { return undefined; } } } if (!path) { return undefined; } if (!name) { name = "sound"; } const candidateFilePath = await ProjectItemManager._generateFileNameForNewItem(project, path, name, "mp3"); if (candidateFilePath === undefined) { return undefined; } const pi = project.ensureItemByProjectPath(candidateFilePath, IProjectItemData_1.ProjectItemStorageType.singleFile, StorageUtilities_1.default.getLeafName(candidateFilePath), IProjectItemData_1.ProjectItemType.audio, undefined, IProjectItemData_1.ProjectItemCreationType.normal); const file = await pi.ensureFileStorage(); if (file !== null) { file.setContent(sourceFile.content); } await ProjectAutogeneration_1.default.updateProjectAutogeneration(project); await project.save(); return pi; } static async createNewWorldTest(project, name, folder) { let path = undefined; if (!project.projectFolder) { return; } if (folder) { path = folder.getFolderRelativePath(project.projectFolder); } else { path = ProjectItemManager.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 ProjectItemManager._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, undefined, IProjectItemData_1.ProjectItemCreationType.normal); const file = await pi.ensureFileStorage(); 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); await project.save(); } } exports.default = ProjectItemManager; //# sourceMappingURL=../maps/app/ProjectItemManager.js.map