UNPKG

@minecraft/creator-tools

Version:

Minecraft Creator Tools command line and libraries.

953 lines 57 kB
"use strict"; // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. Object.defineProperty(exports, "__esModule", { value: true }); exports.NewEntityTypeAddMode = void 0; const StorageUtilities_1 = require("../storage/StorageUtilities"); const MinecraftUtilities_1 = require("../minecraft/MinecraftUtilities"); const IProjectItemData_1 = require("./IProjectItemData"); const Database_1 = require("../minecraft/Database"); const Log_1 = require("../core/Log"); const Utilities_1 = require("../core/Utilities"); const IProjectData_1 = require("./IProjectData"); const BehaviorManifestDefinition_1 = require("../minecraft/BehaviorManifestDefinition"); const NpmPackageDefinition_1 = require("../devproject/NpmPackageDefinition"); const ResourceManifestDefinition_1 = require("../minecraft/ResourceManifestDefinition"); const IGalleryItem_1 = require("./IGalleryItem"); const ProjectItemUtilities_1 = require("./ProjectItemUtilities"); const Pack_1 = require("../minecraft/Pack"); const BlockTypeDefinition_1 = require("../minecraft/BlockTypeDefinition"); const HttpStorage_1 = require("../storage/HttpStorage"); const CartoApp_1 = require("./CartoApp"); const ProjectExporter_1 = require("./ProjectExporter"); const ProjectUpdateRunner_1 = require("../updates/ProjectUpdateRunner"); const ProjectStandard_1 = require("./ProjectStandard"); const ProjectAutogeneration_1 = require("./ProjectAutogeneration"); const MinecraftDefinitions_1 = require("../minecraft/MinecraftDefinitions"); const TypeScriptDefinition_1 = require("../minecraft/TypeScriptDefinition"); const Constants_1 = require("../core/Constants"); var NewEntityTypeAddMode; (function (NewEntityTypeAddMode) { NewEntityTypeAddMode[NewEntityTypeAddMode["baseId"] = 0] = "baseId"; })(NewEntityTypeAddMode = exports.NewEntityTypeAddMode || (exports.NewEntityTypeAddMode = {})); class ProjectUtilities { static async getDefaultFolderForPack(project, packType) { if (packType === Pack_1.PackType.behavior) { return await project.getDefaultBehaviorPackFolder(); } else if (packType === Pack_1.PackType.resource) { return await project.getDefaultResourcePackFolder(); } else if (packType === Pack_1.PackType.skin) { return await project.getDefaultSkinPackFolder(); } throw new Error(); } static async ensureJsonItem(project, jsonContent, fileName) { if (!project.projectFolder) { return undefined; } const typeInfo = ProjectItemUtilities_1.default.inferTypeFromJsonContent(jsonContent, fileName); let packType = typeInfo.packType; if (packType === undefined) { packType = Pack_1.PackType.behavior; } const baseFolder = await ProjectItemUtilities_1.default.getDefaultFolderForType(project, typeInfo.itemType); if (!baseFolder) { return undefined; } let folderPath = baseFolder.getFolderRelativePath(project.projectFolder); if (folderPath === undefined) { return undefined; } fileName = StorageUtilities_1.default.getUniqueChildFolderName(fileName, baseFolder); const contentFile = baseFolder.ensureFile(fileName); contentFile.setContent(jsonContent); contentFile.saveContent(); const relPath = contentFile.getFolderRelativePath(project.projectFolder); if (relPath !== undefined) { return project.ensureItemByProjectPath(relPath, IProjectItemData_1.ProjectItemStorageType.singleFile, fileName, typeInfo.itemType, undefined, IProjectItemData_1.ProjectItemCreationType.normal); } return undefined; } static getItemsFromSearch(project, searchResults) { if (searchResults === undefined) { return []; } const searchItems = []; for (const val of searchResults) { for (const item of project.items) { if (item.projectPath && val.value === item.projectPath) { searchItems.push(item); } } } return searchItems; } static getItemFromAnnotatedValue(project, value) { for (const item of project.items) { if (item.projectPath === value.value) { return item; } } return undefined; } static async hasDocumentationMetadata(folder, depth) { await folder.load(); for (const folderName in folder.folders) { if (folderName === "checkpoint_input" || folderName === "metadata" || folderName === "type_definitions" || folderName === "typedefs") { return true; } if (depth === undefined || depth < 5) { const isMetadata = await ProjectUtilities.hasDocumentationMetadata(folder, depth ? depth + 1 : 1); if (isMetadata) { return true; } } } return false; } static async prepareProjectForDocumentation(project) { await project.ensureProjectFolder(); if (!project.projectFolder) { return; } const hasMetadata = await ProjectUtilities.hasDocumentationMetadata(project.projectFolder); if (hasMetadata) { return; } const result = await Database_1.default.loadPreviewMetadataFolder(); if (result) { project.accessoryFolders = [result]; } } static async getBaseBehaviorPackPath(project) { const bpFolder = await project.ensureDefaultBehaviorPackFolder(); if (project.projectFolder === null) { return undefined; } const defaultPath = bpFolder.getFolderRelativePath(project.projectFolder); return defaultPath; } static async getBaseResourcePackPath(project) { const rpFolder = await project.ensureDefaultResourcePackFolder(); if (project.projectFolder === null) { return undefined; } const defaultPath = rpFolder.getFolderRelativePath(project.projectFolder); return defaultPath; } static async applyScriptEntryPoint(project, newScriptEntryPoint) { project.scriptEntryPoint = newScriptEntryPoint; if (project.editPreference === IProjectData_1.ProjectEditPreference.summarized && project.defaultBehaviorPackUniqueId) { const itemsCopy = project.getItemsCopy(); for (const projectItem of itemsCopy) { if (projectItem.itemType === IProjectItemData_1.ProjectItemType.behaviorPackManifestJson) { await projectItem.ensureFileStorage(); if (projectItem.file) { const manifestJson = await BehaviorManifestDefinition_1.default.ensureOnFile(projectItem.file); if (manifestJson && manifestJson.definition && Utilities_1.default.uuidEqual(manifestJson.definition.header.uuid, project.defaultBehaviorPackUniqueId)) { const sm = manifestJson.ensureScriptModule(project.title, project.description); sm.entry = project.scriptEntryPoint; manifestJson.save(); } } } } } } static async applyDescription(project, newDescription) { project.description = newDescription; if (project.editPreference === IProjectData_1.ProjectEditPreference.summarized && project.defaultBehaviorPackUniqueId) { const itemsCopy = project.getItemsCopy(); for (const projectItem of itemsCopy) { if (projectItem.itemType === IProjectItemData_1.ProjectItemType.packageJson) { await projectItem.ensureFileStorage(); if (projectItem.file) { const npmPackageJson = await NpmPackageDefinition_1.default.ensureOnFile(projectItem.file); if (npmPackageJson && npmPackageJson.definition) { npmPackageJson.definition.description = newDescription; await npmPackageJson.save(); } } } else if (projectItem.itemType === IProjectItemData_1.ProjectItemType.behaviorPackManifestJson) { await projectItem.ensureFileStorage(); if (projectItem.file) { const manifestJson = await BehaviorManifestDefinition_1.default.ensureOnFile(projectItem.file); if (manifestJson && manifestJson.definition && Utilities_1.default.uuidEqual(manifestJson.definition.header.uuid, project.defaultBehaviorPackUniqueId)) { const header = manifestJson.ensureHeader(project.title, project.description); header.description = newDescription; await manifestJson.save(); } } } else if (projectItem.itemType === IProjectItemData_1.ProjectItemType.resourcePackManifestJson) { await projectItem.ensureFileStorage(); if (projectItem.file) { const manifestJson = await ResourceManifestDefinition_1.default.ensureOnFile(projectItem.file); if (manifestJson && manifestJson.definition && Utilities_1.default.uuidEqual(manifestJson.definition.header.uuid, project.defaultResourcePackUniqueId)) { const header = manifestJson.ensureHeader(project.title, project.description); header.description = newDescription; await manifestJson.save(); } } } } } } static async applyCreator(project, newCreator) { project.creator = newCreator; } static async applyShortName(project, newShortName) { project.shortName = newShortName; } static async ensureGeneratedWith(project, isToolWeb) { const appName = isToolWeb ? "mctoolsweb" : "mctoolscli"; if (project.editPreference === IProjectData_1.ProjectEditPreference.summarized && project.defaultBehaviorPackUniqueId) { const itemsCopy = project.getItemsCopy(); for (const projectItem of itemsCopy) { if (projectItem.file && projectItem.itemType === IProjectItemData_1.ProjectItemType.behaviorPackManifestJson) { const bpManifestJson = await BehaviorManifestDefinition_1.default.ensureOnFile(projectItem.file); if (bpManifestJson && bpManifestJson.definition) { bpManifestJson.ensureGeneratedWith(appName, Constants_1.constants.version); await bpManifestJson.save(); } } else if (projectItem.file && projectItem.itemType === IProjectItemData_1.ProjectItemType.resourcePackManifestJson) { const rpManifestJson = await ResourceManifestDefinition_1.default.ensureOnFile(projectItem.file); if (rpManifestJson && rpManifestJson.definition) { rpManifestJson.ensureGeneratedWith(appName, Constants_1.constants.version); await rpManifestJson.save(); } } } } } static async applyTitle(project, newTitle) { project.title = newTitle; if (project.editPreference === IProjectData_1.ProjectEditPreference.summarized && project.defaultBehaviorPackUniqueId) { const itemsCopy = project.getItemsCopy(); for (const projectItem of itemsCopy) { if (projectItem.file && projectItem.itemType === IProjectItemData_1.ProjectItemType.packageJson) { const npmPackageJson = await NpmPackageDefinition_1.default.ensureOnFile(projectItem.file); if (npmPackageJson && npmPackageJson.definition) { npmPackageJson.definition.name = newTitle; await npmPackageJson.save(); } } else if (projectItem.itemType === IProjectItemData_1.ProjectItemType.behaviorPackManifestJson) { await projectItem.ensureFileStorage(); if (projectItem.file) { const manifestJson = await BehaviorManifestDefinition_1.default.ensureOnFile(projectItem.file); if (manifestJson && manifestJson.definition && Utilities_1.default.uuidEqual(manifestJson.definition.header.uuid, project.defaultBehaviorPackUniqueId)) { const header = manifestJson.ensureHeader(project.title, project.description); header.name = newTitle; await manifestJson.save(); } } } else if (projectItem.itemType === IProjectItemData_1.ProjectItemType.resourcePackManifestJson) { await projectItem.ensureFileStorage(); if (projectItem.file) { const manifestJson = await ResourceManifestDefinition_1.default.ensureOnFile(projectItem.file); if (manifestJson && manifestJson.definition && Utilities_1.default.uuidEqual(manifestJson.definition.header.uuid, project.defaultResourcePackUniqueId)) { const header = manifestJson.ensureHeader(project.title, project.description); header.name = newTitle; await manifestJson.save(); } } } } } } static async applyBehaviorPackUniqueId(project, newBehaviorPackId) { const oldBehaviorPackId = project.defaultBehaviorPackUniqueId; await project.setDefaultBehaviorPackUniqueIdAndUpdateDependencies(newBehaviorPackId); if (project.editPreference === IProjectData_1.ProjectEditPreference.summarized && project.defaultBehaviorPackUniqueId) { let bpackCount = 0; const itemsCopy = project.getItemsCopy(); for (const projectItem of itemsCopy) { if (projectItem.itemType === IProjectItemData_1.ProjectItemType.behaviorPackManifestJson) { bpackCount++; } } for (const projectItem of itemsCopy) { if (projectItem.itemType === IProjectItemData_1.ProjectItemType.behaviorPackManifestJson) { await projectItem.ensureFileStorage(); if (projectItem.file) { const manifestJson = await BehaviorManifestDefinition_1.default.ensureOnFile(projectItem.file); if (manifestJson && manifestJson.definition && (bpackCount <= 1 || Utilities_1.default.uuidEqual(manifestJson.definition.header.uuid, project.defaultBehaviorPackUniqueId) || Utilities_1.default.uuidEqual(manifestJson.definition.header.uuid, oldBehaviorPackId))) { const header = manifestJson.ensureHeader(project.title, project.description); header.uuid = newBehaviorPackId; manifestJson.save(); } } } } } } static async applyResourcePackUniqueId(project, newResourcePackId) { const oldResourcePackId = project.defaultResourcePackUniqueId; await project.setDefaultResourcePackUniqueIdAndUpdateDependencies(newResourcePackId); if (project.editPreference === IProjectData_1.ProjectEditPreference.summarized && project.defaultResourcePackUniqueId) { let rpackCount = 0; const itemsCopy = project.getItemsCopy(); for (const projectItem of itemsCopy) { if (projectItem.itemType === IProjectItemData_1.ProjectItemType.resourcePackManifestJson) { rpackCount++; } } for (const projectItem of itemsCopy) { if (projectItem.itemType === IProjectItemData_1.ProjectItemType.resourcePackManifestJson) { await projectItem.ensureFileStorage(); if (projectItem.file) { const manifestJson = await ResourceManifestDefinition_1.default.ensureOnFile(projectItem.file); if (manifestJson && manifestJson.definition && (rpackCount <= 1 || Utilities_1.default.uuidEqual(manifestJson.definition.header.uuid, project.defaultResourcePackUniqueId) || Utilities_1.default.uuidEqual(manifestJson.definition.header.uuid, oldResourcePackId))) { const header = manifestJson.ensureHeader(project.title, project.description); header.uuid = newResourcePackId; manifestJson.save(); } } } } } } static getSuggestedProjectShortName(creator, name) { return this.getSuggestedShortName(creator) + "_" + this.getSuggestedShortName(name); } static getSuggestedShortName(caption) { caption = caption.trim().replace(/-/g, ""); caption = caption.replace(/_/g, ""); caption = caption.replace(/ /g, ""); caption = caption.replace(/:/g, ""); caption = caption.replace(/;/g, ""); caption = caption.replace(/=/g, ""); let capitalStr = ""; for (let i = 0; i < caption.length; i++) { if (caption[i] >= "A" && caption[i] <= "Z") { capitalStr += caption[i].toLowerCase(); } } if (capitalStr.length > 1) { return capitalStr; } if (caption.length <= 4) { return caption.toLowerCase(); } return caption.substring(0, 4).toLowerCase(); } static getSuggestedProjectName(project) { return this.getSuggestedProjectNameFromElements(project.id, project.gitHubFolder, project.gitHubRepoName); } static getSuggestedProjectNameFromElements(id, gitHubFolder, gitHubRepoName) { let projName = "my"; if (id) { projName += id; } else if (gitHubFolder !== undefined) { projName += gitHubFolder; projName = projName.replace(" behavior_packs", ""); } else { projName += gitHubRepoName; } projName = projName.replace(/_/gi, ""); projName = projName.replace(/\//gi, ""); projName = projName.replace(/\\/gi, ""); projName = projName.replace(/ /gi, ""); return projName; } static async getBaseScriptsPath(project) { const scriptsFolder = await project.ensureDefaultScriptsFolder(); if (project.projectFolder === null) { return undefined; } return scriptsFolder.getFolderRelativePath(project.projectFolder); } static async processNewProject(project, title, description, suggestedShortName, isWeb) { await project.inferProjectItemsFromFiles(); if (suggestedShortName) { await ProjectExporter_1.default.renameDefaultFolders(project, suggestedShortName); } await ProjectAutogeneration_1.default.updateProjectAutogeneration(project); await ProjectUtilities.randomizeAllUids(project); await ProjectUtilities.applyTitle(project, title); await ProjectUtilities.applyDescription(project, description); await ProjectUtilities.ensureGeneratedWith(project, isWeb); await ProjectStandard_1.default.ensureIsStandard(project); const pur = new ProjectUpdateRunner_1.default(project); await pur.updateProject(); await project.save(true); } static async setNewModuleId(project, newModuleId, oldModuleId) { const itemsCopy = project.getItemsCopy(); let setResourcePack = false; for (let i = 0; i < itemsCopy.length; i++) { const pi = itemsCopy[i]; if (pi.file) { if (pi.itemType === IProjectItemData_1.ProjectItemType.resourcePackManifestJson && !setResourcePack) { const rpManifestJson = await ResourceManifestDefinition_1.default.ensureOnFile(pi.file); if (rpManifestJson) { if (rpManifestJson.definition && rpManifestJson.definition.modules) { const mods = rpManifestJson.definition.modules; for (const mod of mods) { if (mod.uuid === oldModuleId) { mod.uuid = newModuleId; } } } } } else if (pi.itemType === IProjectItemData_1.ProjectItemType.behaviorPackManifestJson) { const bpManifestJson = await ResourceManifestDefinition_1.default.ensureOnFile(pi.file); if (bpManifestJson) { if (bpManifestJson.definition && bpManifestJson.definition.modules) { const mods = bpManifestJson.definition.modules; for (const mod of mods) { if (mod.uuid === oldModuleId) { mod.uuid = newModuleId; } } } } } } } } static async getDefaultSpawnRulesFolder(project) { const bpFolder = await project.getDefaultBehaviorPackFolder(); if (!bpFolder) { return undefined; } const srFolder = bpFolder.ensureFolder("spawn_rules"); await srFolder.ensureExists(); return srFolder; } static async getDefaultLootTableFolder(project) { const bpFolder = await project.getDefaultBehaviorPackFolder(); if (!bpFolder) { return undefined; } const ltFolder = bpFolder.ensureFolder("loot_table"); await ltFolder.ensureExists(); return ltFolder; } static async getIsAddon(project) { const itemsCopy = project.getItemsCopy(); let rpCount = 0; let bpCount = 0; for (let i = 0; i < itemsCopy.length; i++) { const pi = itemsCopy[i]; if (pi.file) { if (pi.itemType === IProjectItemData_1.ProjectItemType.resourcePackManifestJson) { rpCount++; const rpManifestJson = await ResourceManifestDefinition_1.default.ensureOnFile(pi.file); if (rpManifestJson) { if (!rpManifestJson.hasAddonProperties()) { return false; } } } else if (pi.itemType === IProjectItemData_1.ProjectItemType.behaviorPackManifestJson) { bpCount++; const bpManifestJson = await BehaviorManifestDefinition_1.default.ensureOnFile(pi.file); if (bpManifestJson) { if (!bpManifestJson.hasAddonProperties()) { return false; } } } } } return bpCount === 1 && rpCount === 1; } static async setIsAddon(project) { const itemsCopy = project.getItemsCopy(); for (let i = 0; i < itemsCopy.length; i++) { const pi = itemsCopy[i]; if (pi.file) { if (pi.itemType === IProjectItemData_1.ProjectItemType.resourcePackManifestJson) { const rpManifestJson = await ResourceManifestDefinition_1.default.ensureOnFile(pi.file); if (rpManifestJson) { rpManifestJson.setAddonProperties(); } } else if (pi.itemType === IProjectItemData_1.ProjectItemType.behaviorPackManifestJson) { const bpManifestJson = await BehaviorManifestDefinition_1.default.ensureOnFile(pi.file); if (bpManifestJson) { bpManifestJson.setAddonProperties(); } } } } } static async randomizeAllUids(project) { const oldUids = {}; oldUids["defaultBehaviorPack"] = project.defaultBehaviorPackUniqueId; oldUids["defaultResourcePack"] = project.defaultResourcePackUniqueId; oldUids["defaultDataPack"] = project.defaultDataUniqueId; oldUids["defaultScriptModulePack"] = project.defaultScriptModuleUniqueId; await project.setDefaultResourcePackUniqueIdAndUpdateDependencies(Utilities_1.default.createUuid()); await project.setDefaultBehaviorPackUniqueIdAndUpdateDependencies(Utilities_1.default.createUuid()); project.defaultDataUniqueId = Utilities_1.default.createUuid(); project.defaultScriptModuleUniqueId = Utilities_1.default.createUuid(); const itemsCopy = project.getItemsCopy(); for (let i = 0; i < itemsCopy.length; i++) { const pi = itemsCopy[i]; if (pi.file) { if (pi.itemType === IProjectItemData_1.ProjectItemType.behaviorPackManifestJson) { const bpManifestJson = await BehaviorManifestDefinition_1.default.ensureOnFile(pi.file); if (bpManifestJson) { bpManifestJson.randomizeModuleUuids(project.defaultScriptModuleUniqueId, oldUids["defaultScriptModulePack"]); if (bpManifestJson.id !== oldUids["defaultBehaviorPack"] && bpManifestJson.id !== project.defaultBehaviorPackUniqueId) { await bpManifestJson.setUuid(Utilities_1.default.createUuid(), project); } } } else if (pi.itemType === IProjectItemData_1.ProjectItemType.resourcePackManifestJson) { const rpManifestJson = await ResourceManifestDefinition_1.default.ensureOnFile(pi.file); if (rpManifestJson) { rpManifestJson.randomizeModuleUuids(project.defaultDataUniqueId, oldUids["defaultDataModulePack"]); if (rpManifestJson.id !== oldUids["defaultResourcePack"] && rpManifestJson.id !== project.defaultResourcePackUniqueId) { await rpManifestJson.setUuid(Utilities_1.default.createUuid(), project); } } } } } await project.save(); } static async addEntityTypeFromGallery(project, entityTypeProject, entityTypeName, addMode, messageUpdater, dontOverwriteExistingFiles) { await ProjectUtilities.copyGalleryPackFilesAndFixupIds(project, entityTypeProject, entityTypeName, messageUpdater, dontOverwriteExistingFiles); await project.inferProjectItemsFromFiles(true); const items = project.getItemsCopy(); for (const item of items) { if (item.itemType === IProjectItemData_1.ProjectItemType.entityTypeBehavior) { let minecraftEntityType = (await MinecraftDefinitions_1.default.get(item)); if (minecraftEntityType) { const targetId = entityTypeName ? entityTypeName : entityTypeProject.id; if (minecraftEntityType.id?.endsWith(targetId)) { minecraftEntityType.runtimeIdentifier = entityTypeProject.targetRuntimeIdentifier ? entityTypeProject.targetRuntimeIdentifier : "minecraft:" + entityTypeProject.id; minecraftEntityType.persist(); } } } } await project.save(); } static async addBlockTypeFromGallery(project, blockTypeProject, blockTypeName) { await ProjectUtilities.copyGalleryPackFilesAndFixupIds(project, blockTypeProject, blockTypeName); await project.inferProjectItemsFromFiles(true); await project.save(); } static async addItemTypeFromGallery(project, blockTypeProject, blockTypeName) { await ProjectUtilities.copyGalleryPackFilesAndFixupIds(project, blockTypeProject, blockTypeName); await project.inferProjectItemsFromFiles(true); await project.save(); } static async copyGalleryPackFilesAndFixupIds(project, galleryProject, newTypeName, messagerUpdater, dontOverwriteExistingFiles) { const files = galleryProject.fileList; if (files === undefined) { Log_1.default.unexpectedUndefined("AETFLS"); return; } if (newTypeName === undefined) { newTypeName = galleryProject.id; } let sourceBpFolder = undefined; let sourceRpFolder = undefined; if (galleryProject.gitHubRepoName === "bedrock-samples") { sourceBpFolder = await Database_1.default.getReleaseVanillaBehaviorPackFolder(); sourceRpFolder = await Database_1.default.getReleaseVanillaResourcePackFolder(); } else { const gh = new HttpStorage_1.default(CartoApp_1.default.contentRoot + "res/samples/" + galleryProject.gitHubOwner + "/" + galleryProject.gitHubRepoName + "-" + (galleryProject.gitHubBranch ? galleryProject.gitHubBranch : "main") + "/" + galleryProject.gitHubFolder); //new GitHubStorage(carto.anonGitHub, gitHubRepoName, gitHubOwner, gitHubBranch, gitHubFolder); await gh.rootFolder.load(); const bps = gh.rootFolder.folders["behavior_packs"]; const rps = gh.rootFolder.folders["resource_packs"]; if (!bps || !rps) { Log_1.default.unexpectedUndefined("AETFLT"); return; } await rps.load(); await bps.load(); if (rps.folderCount < 1 || bps.folderCount < 1) { Log_1.default.unexpectedUndefined("AETFLY"); return; } sourceBpFolder = bps.getFolderByIndex(0); sourceRpFolder = rps.getFolderByIndex(0); } const targetBpFolder = await project.ensureDefaultBehaviorPackFolder(); const targetRpFolder = await project.ensureDefaultResourcePackFolder(); if (!sourceBpFolder || !sourceRpFolder || !sourceBpFolder || !sourceRpFolder || !targetBpFolder || !targetRpFolder) { Log_1.default.unexpectedUndefined("AETVA"); return; } let contentReplacements = ['"identifier"', '"materials"']; if (galleryProject.type === IGalleryItem_1.GalleryItemType.itemType || galleryProject.type === IGalleryItem_1.GalleryItemType.blockType) { contentReplacements = ['"materials"']; } for (const filePath of files) { if (filePath.startsWith("/behavior_pack")) { let subPath = undefined; if (filePath.startsWith("/behavior_pack/")) { subPath = filePath.substring(14); } else { const nextSlash = filePath.indexOf("/", 16); if (nextSlash < 0) { Log_1.default.unexpectedUndefined("AETVB"); return; } subPath = filePath.substring(nextSlash); } const targetPath = ProjectUtilities.replaceNamesInPath(subPath, project, galleryProject, newTypeName); const sourceFile = await sourceBpFolder.getFileFromRelativePath(subPath); if (!sourceFile) { Log_1.default.debugAlert("Could not find file '" + subPath + "'"); } else { const targetFile = await targetBpFolder.ensureFileFromRelativePath(targetPath); let update = true; if (dontOverwriteExistingFiles) { const targetExists = await targetFile.exists(); if (targetExists) { update = false; } } if (update) { await sourceFile.loadContent(); let content = sourceFile.content; if (typeof content === "string") { content = ProjectUtilities.replaceNamesInContent(content, project, galleryProject, newTypeName, contentReplacements); } if (content !== null) { if (messagerUpdater) { messagerUpdater("Updating '" + targetFile.fullPath + "'"); } targetFile.setContent(content); } } } } else if (filePath.startsWith("/resource_pack")) { let subPath = undefined; if (filePath.startsWith("/resource_pack/")) { subPath = filePath.substring(14); } else { const nextSlash = filePath.indexOf("/", 16); if (nextSlash < 0) { Log_1.default.unexpectedUndefined("AETVC"); return; } subPath = filePath.substring(nextSlash); } const targetPath = ProjectUtilities.replaceNamesInPath(subPath, project, galleryProject, newTypeName); const sourceFile = await sourceRpFolder.getFileFromRelativePath(subPath); if (!sourceFile) { Log_1.default.debugAlert("Could not find file '" + subPath + "'"); } else { const targetFile = await targetRpFolder.ensureFileFromRelativePath(targetPath); let update = true; if (update) { if (dontOverwriteExistingFiles) { const targetExists = await targetFile.exists(); if (targetExists) { update = false; } } await sourceFile.loadContent(); let content = sourceFile.content; if (typeof content === "string") { content = ProjectUtilities.replaceNamesInContent(content, project, galleryProject, newTypeName, contentReplacements); } if (content !== null) { if (messagerUpdater) { messagerUpdater("Updating '" + targetFile.fullPath + "'"); } targetFile.setContent(content); } } } } } } static replaceNamesInPath(path, project, galleryProject, newName) { let pathReplacers = galleryProject.nameReplacers; if (!pathReplacers) { pathReplacers = [galleryProject.id]; } newName = newName.toLowerCase(); newName = newName.replace(/-/g, "_"); newName = newName.replace(/ /g, "_"); for (const pathReplacer of pathReplacers) { path = Utilities_1.default.replaceAll(path, "/" + pathReplacer + ".", "/" + newName + "."); path = Utilities_1.default.replaceAll(path, "\\" + pathReplacer + ".", "\\" + newName + "."); path = Utilities_1.default.replaceAll(path, "/" + pathReplacer + "/", "/" + newName + "/"); path = Utilities_1.default.replaceAll(path, "\\" + pathReplacer + "\\", "\\" + newName + "\\"); path = Utilities_1.default.replaceAll(path, "/" + pathReplacer + "_ico.", "/" + newName + "_ico."); path = Utilities_1.default.replaceAll(path, "\\" + pathReplacer + "_ico.", "\\" + newName + "_ico."); path = Utilities_1.default.replaceAll(path, "/" + pathReplacer + "_ico/", "/" + newName + "_ico/"); path = Utilities_1.default.replaceAll(path, "\\" + pathReplacer + "_ico\\", "\\" + newName + "_ico\\"); } return path; } static replaceNamesInContent(content, project, galleryProject, newName, replaceAllExclusions) { let replacers = galleryProject.nameReplacers; if (!replacers) { replacers = [galleryProject.id]; } newName = newName.toLowerCase(); newName = newName.replace(/-/g, "_"); newName = newName.replace(/ /g, "_"); for (const replacer of replacers) { content = Utilities_1.default.replaceAll(content, "minecraft:" + replacer, project.effectiveDefaultNamespace + ":" + newName); content = Utilities_1.default.replaceAll(content, "demo:" + replacer, project.effectiveDefaultNamespace + ":" + newName); content = Utilities_1.default.replaceAll(content, "starter:" + replacer, project.effectiveDefaultNamespace + ":" + newName); content = Utilities_1.default.replaceAll(content, "sample:" + replacer, project.effectiveDefaultNamespace + ":" + newName); content = Utilities_1.default.replaceAllExceptInLines(content, ":" + replacer, ":" + newName, replaceAllExclusions); content = Utilities_1.default.replaceAllExceptInLines(content, "/" + replacer, "/" + newName, replaceAllExclusions); content = Utilities_1.default.replaceAllExceptInLines(content, "." + replacer, "." + newName, replaceAllExclusions); content = Utilities_1.default.replaceAllExceptInLines(content, '"' + replacer + '"', '"' + newName + '"', replaceAllExclusions); } return content; } static getTopicUrl(topic) { const tokens = topic.split("."); if (tokens.length < 1) { return undefined; } if (this.ImportTypes.mc.includes(tokens[0]) || tokens[0] === "World" || tokens[0] === "System" || tokens[0] === "Dimension") { return ("https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/" + topic.toLowerCase().replace(".", "#")); } if (this.ImportTypes.mcui.includes(tokens[0])) { return ("https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server-ui/" + topic.toLowerCase().replace(".", "#")); } if (this.ImportTypes.mced.includes(tokens[0])) { return ("https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server-editor/" + topic.toLowerCase().replace(".", "#")); } return undefined; } static adaptFullSample(content) { const registerFunction = content.indexOf("export function register"); if (registerFunction >= 0) { let nextParen = content.indexOf("Extension(", registerFunction); if (nextParen > registerFunction) { content = content.substring(0, registerFunction + 24) + content.substring(nextParen); } } return content; } static adaptSample(sampleContent, fileContent) { if (sampleContent.indexOf(" mc.") >= 0 && fileContent.indexOf(" as mc") <= 0) { sampleContent = sampleContent.replace(/mc./gi, ""); } if (sampleContent.indexOf(" mcui.") >= 0 && fileContent.indexOf(" as mcui") <= 0) { sampleContent = sampleContent.replace(/mcui./gi, ""); } return sampleContent; } static modifyImports(fileContent) { let startOfCode = fileContent.indexOf("("); let nextStartOfCode = fileContent.indexOf("function"); if (nextStartOfCode >= 0 && nextStartOfCode < startOfCode) { startOfCode = nextStartOfCode; } nextStartOfCode = fileContent.indexOf("class"); if (nextStartOfCode >= 0 && nextStartOfCode < startOfCode) { startOfCode = nextStartOfCode; } const previousNewLine = fileContent.lastIndexOf("\n", startOfCode); if (previousNewLine >= 0) { startOfCode = previousNewLine; } if (startOfCode > 0) { let introContent = fileContent.substring(0, startOfCode); const restOfContent = fileContent.substring(startOfCode); introContent = ProjectUtilities.ensureImportLines(introContent, restOfContent, "@minecraft/server", this.ImportTypes.mc); introContent = ProjectUtilities.ensureImportLines(introContent, restOfContent, "@minecraft/server-ui", this.ImportTypes.mcui); introContent = ProjectUtilities.ensureImportLines(introContent, restOfContent, "@minecraft/vanilla-data", this.ImportTypes.vanilla); introContent = ProjectUtilities.ensureImportLines(introContent, restOfContent, "@minecraft/math", this.ImportTypes.math); fileContent = introContent + restOfContent; } return fileContent; } static ensureImportLines(introSection, restOfContent, moduleName, importCollection) { for (const importType of importCollection) { if (restOfContent.indexOf(importType) >= 0) { let importLineIndex = introSection.indexOf('from "' + moduleName + '";'); if (importLineIndex < 0) { introSection = 'import {} from "' + moduleName + '";\r\n' + introSection; importLineIndex = 10; } let previousNewLine = introSection.lastIndexOf("\n", importLineIndex); if (previousNewLine < 0) { previousNewLine = 0; } let endNewLine = introSection.indexOf("\n", importLineIndex); if (endNewLine > previousNewLine) { let importLine = introSection.substring(previousNewLine, endNewLine); const leftBracket = importLine.indexOf("{"); const rightBracket = importLine.indexOf("}"); if (leftBracket > 0 && rightBracket > leftBracket) { const interior = importLine.substring(leftBracket + 1, rightBracket).trim(); let injectToken = importType; // is there one token already in the import linte if (interior.length > 0) { injectToken = ", " + injectToken; } importLine = importLine.substring(0, rightBracket) + injectToken + importLine.substring(rightBracket); } introSection = introSection.substring(0, previousNewLine) + importLine + introSection.substring(endNewLine); } } } return introSection; } static async ensureTypeScriptFileWith(project, token, templateSet, templateName, fileNameCore, replacers) { const itemsCopy = project.getItemsCopy(); for (const projectItem of itemsCopy) { if (projectItem.itemType === IProjectItemData_1.ProjectItemType.ts) { await projectItem.ensureFileStorage(); if (projectItem.file) { const tsJson = await TypeScriptDefinition_1.default.ensureOnFile(projectItem.file); if (tsJson?.data && tsJson.data.indexOf(token) >= 0) { return; } } } } const snippet = await Database_1.default.getSnippet(templateSet, templateName); const scriptFolder = await project.ensureDefaultScriptsFolder(); await scriptFolder.load(); if (!snippet) { Log_1.default.error("Could not find template " + templateSet, templateName); return; } const file = scriptFolder.ensureFile(fileNameCore + ".ts"); let snippetInjectContent = "\r\n" + snippet.body.join("\n") + "\r\n"; for (const replacerToken in replacers) { const targetReplace = replacers[replacerToken]; if (targetReplace) { // replace with something better. while (snippetInjectContent.indexOf(replacerToken) >= 0) { snippetInjectContent = snippetInjectContent.replace(replacerToken, replacers[replacerToken]); } } } file.setContent(snippetInjectContent); await file.saveContent(); await project.inferProjectItemsFromFiles(true); } static async injectSnippet(project, snippet, fullScriptBoxReplace) { let snippetInjectContent = "\r\n" + snippet.body.join("\n") + "\r\n"; const folder = await project.ensureDefaultScriptsFolder(); await folder.load(); // Log.debugAlert("Inject snippet considering folder: " + folder.storageRelativePath + "|" + replaceContent); for (const fileName in folder.files) { const file = folder.files[fileName]; if (file !== undefined) { if (fullScriptBoxReplace && fileName === "ScriptBox.ts") { snippetInjectContent = ProjectUtilities.adaptFullSample(snippetInjectContent); file.setContent(snippetInjectContent); } else { const type = StorageUtilities_1.default.getTypeFromName(file.name); if (type === "ts" || type === "js") { await file.loadContent(); // Log.debugAlert("Inject snippet considering file: " + file.storageRelativePath + "|" + file.content?.length); if (file.content && typeof file.content === "string") { let content = file.content; for (let i = 0; i < this.CodeReplaceTokens.length; i++) { const token = content.indexOf(this.CodeReplaceTokens[i]); if (token >= 0) { const previousNewLine = content.lastIndexOf("\n", token); const nextNewLine = content.indexOf("\n", token); if (previousNewLine >= 0 && nextNewLine > previousNewLine) { snippetInjectContent = ProjectUtilities.adaptSample(snippetInjectContent, content); content = content.substring(0, previousNewLine) + snippetInjectContent + content.substring(nextNewLine + 1); if (snippetInjectContent.indexOf("overworld") >= 0 && snippetInjectContent.indexOf("const overworld") <= 0) { let firstComment = content.indexOf("//"); if (firstComment >= 0) { content = content.substring(0, firstComment) + ' const overworld = mc.world.getDimension("overworld");\r\n' + content.substring(firstComment, content.length); } } content = ProjectUtilities.modifyImports(content); file.setContent(content); } } } } } } } } } static async addBlockType(project, blockTypeId, blockTypeName) { const defaultBehaviorPackPath = await ProjectUtilities.getBaseBehaviorPackPath(project); const defaultScriptsPath = await ProjectUtilities.getBaseScriptsPath(project); if (defaultBehaviorPackPath === undefined || defaultScriptsPath === undefined) { return; } await Database_1.default.getReleaseVanillaBehaviorPackFolder(); if (Database_1.default.releaseVanillaBehaviorPackFolder === null) { Log_1.default.fail("Could not find default behavior pack folder"); return; } const sourceFile = Database_1.default.releaseVanillaBehaviorPackFolder .ensureFolder("blocks") .ensureFile(blockTypeId + ".json"); await sourceFil