UNPKG

@minecraft/creator-tools

Version:

Minecraft Creator Tools command line and libraries.

761 lines (760 loc) 36.8 kB
"use strict"; // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.ProjectImportExclusions = void 0; const MCWorld_1 = __importDefault(require("./../minecraft/MCWorld")); const StorageUtilities_1 = __importDefault(require("./../storage/StorageUtilities")); const Utilities_1 = __importDefault(require("../core/Utilities")); const Database_1 = __importDefault(require("./../minecraft/Database")); const Log_1 = __importDefault(require("../core/Log")); const GitHubStorage_1 = __importDefault(require("./../github/GitHubStorage")); const AppServiceProxy_1 = __importStar(require("./../core/AppServiceProxy")); const ZipStorage_1 = __importDefault(require("../storage/ZipStorage")); const IProjectData_1 = require("../app/IProjectData"); const ProjectUpdateRunner_1 = __importDefault(require("../updates/ProjectUpdateRunner")); const CreatorToolsHost_1 = __importDefault(require("./CreatorToolsHost")); const HttpStorage_1 = __importDefault(require("../storage/HttpStorage")); const ProjectBuild_1 = __importDefault(require("./ProjectBuild")); const WorldLevelDat_1 = require("../minecraft/WorldLevelDat"); const IProjectItemData_1 = require("./IProjectItemData"); const ProjectUtilities_1 = __importDefault(require("./ProjectUtilities")); const Telemetry_1 = __importDefault(require("../analytics/Telemetry")); const TelemetryConstants_1 = require("../analytics/TelemetryConstants"); const GalleryReader_1 = __importDefault(require("./gallery/GalleryReader")); exports.ProjectImportExclusions = [ "build", "node_modules", "dist", "lib", ".env", "*/.*", "out", "*just.config*", "*package-lock*", "*.mjs*", "index.json", ]; class ProjectExporter { static async generateFlatBetaApisWorldWithPacksZipBytes(creatorTools, project, name) { await Database_1.default.loadContent(); if (Database_1.default.contentFolder === null) { Log_1.default.unexpectedNull(); return undefined; } const mcworld = await this.generateWorldWithPacksAndContent(project, name, undefined, { generator: WorldLevelDat_1.Generator.flat, betaApisExperiment: true, }); if (!mcworld) { return undefined; } const newBytes = await mcworld.getBytes(); // Track pack info for flat world const properties = {}; const additionalPackCount = (mcworld.worldBehaviorPacks?.length || 0) + (mcworld.worldResourcePacks?.length || 0); properties[TelemetryConstants_1.TelemetryProperties.ADDITIONAL_PACKS_ADDED] = additionalPackCount > 0 ? additionalPackCount : undefined; const behaviorPackUuids = mcworld.worldBehaviorPacks?.map((pack) => pack.pack_id)?.join(";"); properties[TelemetryConstants_1.TelemetryProperties.BEHAVIOR_PACKS] = behaviorPackUuids || ""; const resourcePackUuids = mcworld.worldResourcePacks?.map((pack) => pack.pack_id)?.join(";"); properties[TelemetryConstants_1.TelemetryProperties.RESOURCE_PACKS] = resourcePackUuids || ""; Telemetry_1.default.trackEvent({ name: TelemetryConstants_1.TelemetryEvents.FLAT_WORLD_DOWNLOADED, properties, }); return newBytes; } static async syncProjectFromGitHub(isNewProject, creatorTools, gitHubRepoName, gitHubOwner, gitHubBranch, gitHubFolder, projName, project, fileList, messageUpdater, dontOverwriteExistingFiles) { let gh = undefined; // Use GalleryReader to map repo names to local folder names (e.g., // "minecraft-scripting-samples" → "script-samples") for bundled content. const localRepoFolder = GalleryReader_1.default.getLocalRepoFolder(gitHubRepoName, gitHubBranch); const localUrlExtension = "res/samples/" + gitHubOwner + "/" + localRepoFolder + "/" + gitHubFolder; if (CreatorToolsHost_1.default.isWeb) { gh = HttpStorage_1.default.get(Utilities_1.default.ensureEndsWithSlash(CreatorToolsHost_1.default.contentWebRoot) + localUrlExtension); } else if (creatorTools.local) { // In Node.js contexts (CLI, VS Code, Electron), use bundled samples from the // local package instead of downloading from GitHub. This is faster, works offline, // and avoids GitHub API rate limits for unauthenticated requests. const localGh = creatorTools.local.createStorage(localUrlExtension); if (localGh) { try { // Verify the local folder actually exists before committing to it const exists = await localGh.rootFolder.exists(); if (exists) { gh = localGh; } } catch { // Local storage not available, will fall back to GitHub } } } // Fall back to GitHub if bundled samples aren't available if (!gh) { gh = new GitHubStorage_1.default(creatorTools.anonGitHub, gitHubRepoName, gitHubOwner, gitHubBranch, gitHubFolder); } if (!projName) { projName = "local " + gitHubOwner + " " + gitHubRepoName; if (gitHubFolder !== undefined) { projName += " " + gitHubFolder.replace(/\//gi, " "); projName = projName.replace(" behavior_packs", ""); } } const newProjectName = await creatorTools.getNewProjectName(projName); if (!project) { project = await creatorTools.createNewProject(newProjectName, undefined, undefined, undefined, IProjectData_1.ProjectFocus.gameTests, false); } /*if (fileList) { await gh.rootFolder.setStructureFromFileList(fileList); } else {*/ await gh.rootFolder.load(); //} const rootFolder = await project.ensureProjectFolder(); try { await StorageUtilities_1.default.syncFolderTo(gh.rootFolder, rootFolder, false, false, false, exports.ProjectImportExclusions, undefined, messageUpdater, dontOverwriteExistingFiles); } catch (e) { Log_1.default.error("Error synchronizing from GitHub:" + e.toString()); } await rootFolder.saveAll(); if (isNewProject) { await ProjectUtilities_1.default.renameDefaultFolders(project, projName); project.originalGitHubOwner = gitHubOwner; project.originalGitHubRepoName = gitHubRepoName; project.originalGitHubBranch = gitHubBranch; project.originalGitHubFolder = gitHubFolder; project.originalFileList = fileList; } await project.inferProjectItemsFromFiles(true); const pur = new ProjectUpdateRunner_1.default(project); await pur.updateProject(); await project.save(true); await creatorTools.save(); return project; } static async getPackFolder(folder, seekingResource) { await folder.load(); const manifest = folder.files["manifest.json"]; if (manifest !== undefined) { const parentFolder = folder.parentFolder; let isResource = false; if (parentFolder !== null) { const name = StorageUtilities_1.default.canonicalizeName(parentFolder.name); if (name.indexOf("resource") >= 0) { isResource = true; } } if (seekingResource && isResource) { return folder; } else if (!seekingResource) { return folder; } } else { for (const folderName in folder.folders) { const childFolder = folder.folders[folderName]; if (childFolder !== undefined && !childFolder.errorStatus) { const result = (await ProjectExporter.getPackFolder(childFolder, seekingResource)); if (result !== undefined) { return result; } } } } return undefined; } static async ensureWorldsFolder(rootMinecraftFolder) { let worldsFolder = await rootMinecraftFolder.getFolderFromRelativePath("/minecraftWorlds/"); if (!worldsFolder) { worldsFolder = await rootMinecraftFolder.getFolderFromRelativePath("/worlds/"); } if (!worldsFolder) { worldsFolder = await rootMinecraftFolder.ensureFolderFromRelativePath("/minecraftWorlds/"); } if (!worldsFolder) { Log_1.default.unexpectedUndefined("EWF"); return undefined; } await worldsFolder.ensureExists(); return worldsFolder; } static async ensureMinecraftWorldsFolder(creatorTools) { if (!creatorTools.defaultDeploymentStorage) { Log_1.default.unexpectedUndefined("EMWF"); return undefined; } let isAvailable = creatorTools.defaultDeploymentStorage.available; if (isAvailable === undefined) { isAvailable = await creatorTools.defaultDeploymentStorage.getAvailable(); } if (!isAvailable) { return; } return await this.ensureWorldsFolder(creatorTools.defaultDeploymentStorage.rootFolder); } static async prepareProject(project) { await ProjectExporter.updateProjects(project); await project.save(); const projectBuild = new ProjectBuild_1.default(project); await projectBuild.build(); if (projectBuild.isInErrorState) { project.appendErrors(projectBuild); return undefined; } return projectBuild; } static async deployProject(creatorTools, project, deployTargetFolder, folderDeploy = 1 /* FolderDeploy.developmentFolders */) { const ctProjectBuild = await ProjectExporter.prepareProject(project); if (!ctProjectBuild) { return false; } await ProjectExporter.deployProjectPacks(project, ctProjectBuild, deployTargetFolder, undefined, folderDeploy); await deployTargetFolder.saveAll(); const rpFolderName = folderDeploy === 2 /* FolderDeploy.noFolders */ ? undefined : folderDeploy === 1 /* FolderDeploy.developmentFolders */ ? "development_resource_packs" : "resource_packs"; if (rpFolderName) { const targetResourcePacksFolder = deployTargetFolder.ensureFolder(rpFolderName); const rpDeployFolderExists = await targetResourcePacksFolder.exists(); if (rpDeployFolderExists) { await project.ensureProjectFolder(); const rpi = await project.getDefaultResourcePackFolder(); if (rpi) { const deployProjectFolder = targetResourcePacksFolder.ensureFolder(project.name); await deployProjectFolder.ensureExists(); await StorageUtilities_1.default.syncFolderTo(rpi, deployProjectFolder, true, true, true, [ "/mcworlds", "/minecraftWorlds", ]); } } } return true; } static async deployProjectPacks(project, projectBuild, targetFolder, mcworld, useDeveloperFolders) { const bpGroupFolder = useDeveloperFolders === 2 /* FolderDeploy.noFolders */ ? targetFolder : targetFolder.ensureFolder(useDeveloperFolders === 1 /* FolderDeploy.developmentFolders */ ? "development_behavior_packs" : "behavior_packs"); await bpGroupFolder.ensureExists(); const activeBehaviorPackFolder = await project.getDefaultBehaviorPackFolder(); const scriptsFolder = await project.getMainScriptsFolder(); if (activeBehaviorPackFolder) { const bpTargetFolder = bpGroupFolder.ensureFolder(activeBehaviorPackFolder.ensuredName + (useDeveloperFolders === 2 /* FolderDeploy.noFolders */ ? "_bp" : "")); await bpTargetFolder.ensureExists(); await StorageUtilities_1.default.syncFolderTo(activeBehaviorPackFolder, bpTargetFolder, true, true, false, [ "mcworlds", "db", "level.dat", "level.dat_old", "levelname.txt", "behavior_packs", "resource_packs", ]); await projectBuild.syncToBehaviorPack(bpTargetFolder); if (scriptsFolder && scriptsFolder.parentFolder !== activeBehaviorPackFolder) { const scriptsTargetFolder = bpTargetFolder.ensureFolder("scripts"); await scriptsTargetFolder.ensureExists(); await StorageUtilities_1.default.syncFolderTo(scriptsFolder, scriptsTargetFolder, true, true, false, ["*.ts"]); } if (mcworld) { mcworld.ensureBehaviorPack(project.defaultBehaviorPackUniqueId, project.defaultBehaviorPackVersion, activeBehaviorPackFolder.name); } await bpTargetFolder.saveAll(); } const activeResourcePackFolder = await project.getDefaultResourcePackFolder(); if (activeResourcePackFolder) { const rpGroupFolder = useDeveloperFolders === 2 /* FolderDeploy.noFolders */ ? targetFolder : targetFolder.ensureFolder(useDeveloperFolders === 1 /* FolderDeploy.developmentFolders */ ? "development_resource_packs" : "resource_packs"); await rpGroupFolder.ensureExists(); const rpTargetFolder = rpGroupFolder.ensureFolder(activeResourcePackFolder.ensuredName + (useDeveloperFolders === 2 /* FolderDeploy.noFolders */ ? "_rp" : "")); await rpTargetFolder.ensureExists(); await StorageUtilities_1.default.syncFolderTo(activeResourcePackFolder, rpTargetFolder, true, true, false, [ "mcworlds", "db", "level.dat", "level.dat_old", "levelname.txt", "behavior_packs", "resource_packs", ]); if (mcworld) { mcworld.ensureResourcePack(project.defaultResourcePackUniqueId, project.defaultResourcePackVersion, activeResourcePackFolder.name); await rpTargetFolder.saveAll(); } } } static async deployAsWorldAndTestAssets(creatorTools, project, worldProjectItem, returnZipBytes, deployFolder) { let mcworld; const operId = await creatorTools.notifyOperationStarted("Deploying world '" + worldProjectItem.name + "' and test assets."); if (!worldProjectItem.isContentLoaded) { await worldProjectItem.loadContent(); } const itemFile = worldProjectItem.primaryFile; if (!itemFile && !worldProjectItem.defaultFolder) { Log_1.default.unexpectedUndefined("DAWATA"); return; } if (worldProjectItem.defaultFolder) { mcworld = await MCWorld_1.default.ensureMCWorldOnFolder(worldProjectItem.defaultFolder, project); } else if (itemFile) { mcworld = await MCWorld_1.default.ensureOnFile(itemFile, project); } if (!mcworld) { Log_1.default.debugAlert("Could not find respective world."); return; } const projectBuild = await ProjectExporter.prepareProject(project); if (!projectBuild) { await creatorTools.notifyOperationEnded(operId, "Packaging the world not be completed.", undefined, true); return; } const dateNow = new Date(); const title = mcworld.name + " - " + Utilities_1.default.getFriendlySummary(dateNow); let targetFolder; let zipStorage; if (deployFolder) { const worldsFolder = await ProjectExporter.ensureWorldsFolder(deployFolder); if (!worldsFolder) { Log_1.default.unexpectedUndefined("DAWATAB"); return; } targetFolder = worldsFolder.ensureFolder(title); await targetFolder.ensureExists(); } else if (returnZipBytes) { zipStorage = new ZipStorage_1.default(); targetFolder = zipStorage.rootFolder; } else { const worldsFolder = await ProjectExporter.ensureMinecraftWorldsFolder(creatorTools); if (!worldsFolder) { Log_1.default.unexpectedUndefined("DAWATAC"); return; } targetFolder = worldsFolder.ensureFolder(title); await targetFolder.ensureExists(); } await mcworld.syncFolderTo(targetFolder); if (projectBuild) { await ProjectExporter.deployProjectPacks(project, projectBuild, targetFolder, mcworld); } const creatorToolsProject = await Database_1.default.ensureCreatorToolsIngameProject(); if (creatorToolsProject) { const ctProjectBuild = await ProjectExporter.prepareProject(creatorToolsProject); if (ctProjectBuild) { await ProjectExporter.deployProjectPacks(creatorToolsProject, ctProjectBuild, targetFolder, mcworld); } await mcworld.save(); } await targetFolder.saveAll(); const newMcWorld = await MCWorld_1.default.ensureMCWorldOnFolder(targetFolder); if (!newMcWorld) { Log_1.default.debugAlert("Could not build new world."); return; } // newMcWorld.betaApisExperiment = true; await targetFolder.saveAll(); await newMcWorld.save(); await creatorTools.notifyOperationEnded(operId, "World + local test assets deploy completed."); if (zipStorage) { const zipBytes = await zipStorage.generateUint8ArrayAsync(); return zipBytes; } return undefined; } static async deployAsWorld(creatorTools, project, worldProjectItem, returnZipBytes, deployFolder) { let mcworld; const operId = await creatorTools.notifyOperationStarted("Deploying world '" + worldProjectItem.name + "'"); if (!worldProjectItem.isContentLoaded) { await worldProjectItem.loadContent(); } if (!worldProjectItem.primaryFile && !worldProjectItem.defaultFolder) { Log_1.default.unexpectedUndefined("DAWATA"); return; } if (worldProjectItem.defaultFolder) { mcworld = await MCWorld_1.default.ensureMCWorldOnFolder(worldProjectItem.defaultFolder, project); } else if (worldProjectItem.primaryFile) { mcworld = await MCWorld_1.default.ensureOnFile(worldProjectItem.primaryFile, project); } if (!mcworld) { Log_1.default.debugAlert("Could not find respective world."); return; } const projectBuild = await ProjectExporter.prepareProject(project); if (!projectBuild) { await creatorTools.notifyOperationEnded(operId, "Packaging the world not be completed.", undefined, true); return; } const dateNow = new Date(); const title = mcworld.name + " - " + Utilities_1.default.getFriendlySummary(dateNow); let targetFolder; let zipStorage; if (deployFolder) { const worldsFolder = await ProjectExporter.ensureWorldsFolder(deployFolder); if (!worldsFolder) { Log_1.default.unexpectedUndefined("DAWATAB"); return; } targetFolder = worldsFolder.ensureFolder(title); await targetFolder.ensureExists(); } else if (returnZipBytes) { zipStorage = new ZipStorage_1.default(); targetFolder = zipStorage.rootFolder; } else { const worldsFolder = await ProjectExporter.ensureMinecraftWorldsFolder(creatorTools); if (!worldsFolder) { Log_1.default.unexpectedUndefined("DAWATAC"); return; } targetFolder = worldsFolder.ensureFolder(title); await targetFolder.ensureExists(); } await mcworld.syncFolderTo(targetFolder); await targetFolder.saveAll(); await creatorTools.notifyOperationEnded(operId, "World + local assets deploy completed."); if (zipStorage) { const zipBytes = await zipStorage.generateUint8ArrayAsync(); return zipBytes; } return undefined; } static async updateProjects(project) { const pur = new ProjectUpdateRunner_1.default(project); await pur.updateProject(["SCRIPTMODULE"]); } static async generateWorldWithPacks(creatorTools, project, worldSettings, targetFolder) { const operId = await creatorTools.notifyOperationStarted("Generating world and packs for '" + project.name + "'."); const projectBuild = await ProjectExporter.prepareProject(project); if (projectBuild === undefined) { await creatorTools.notifyOperationEnded(operId); return; } let mcworld = undefined; if (targetFolder === undefined) { mcworld = new MCWorld_1.default(); mcworld.ensureZipStorage(); targetFolder = mcworld.effectiveRootFolder; if (targetFolder === undefined) { Log_1.default.throwUnexpectedUndefined("PEPW"); return; } } else { mcworld = await MCWorld_1.default.ensureMCWorldOnFolder(targetFolder); } if (!mcworld) { Log_1.default.debugAlert("Could not find respective world."); return; } await mcworld.loadMetaFiles(false); await mcworld.applyWorldSettings(worldSettings); await ProjectExporter.ensureExperimentsEnabledOnWorld(mcworld, project); if (projectBuild) { await ProjectExporter.deployProjectPacks(project, projectBuild, targetFolder, mcworld); } mcworld.name = project.name; await targetFolder.saveAll(); await mcworld.save(); const properties = {}; const additionalPackCount = (mcworld.worldBehaviorPacks?.length || 0) + (mcworld.worldResourcePacks?.length || 0); properties[TelemetryConstants_1.TelemetryProperties.ADDITIONAL_PACKS_ADDED] = additionalPackCount > 0 ? additionalPackCount : undefined; const behaviorPackUuids = mcworld.worldBehaviorPacks?.map((pack) => pack.pack_id)?.join(";"); properties[TelemetryConstants_1.TelemetryProperties.BEHAVIOR_PACKS] = behaviorPackUuids || ""; const resourcePackUuids = mcworld.worldResourcePacks?.map((pack) => pack.pack_id)?.join(";"); properties[TelemetryConstants_1.TelemetryProperties.RESOURCE_PACKS] = resourcePackUuids || ""; const levelDat = mcworld.levelData; if (levelDat) { properties[TelemetryConstants_1.TelemetryProperties.GAME_TYPE] = levelDat.gameType; properties[TelemetryConstants_1.TelemetryProperties.DIFFICULTY] = levelDat.difficulty; properties[TelemetryConstants_1.TelemetryProperties.MAP_STYLE] = levelDat.generator ?? (levelDat.flatWorldLayers ? "flat" : undefined); properties[TelemetryConstants_1.TelemetryProperties.SEED] = levelDat.randomSeed; } properties[TelemetryConstants_1.TelemetryProperties.WORLD_TEMPLATE_USED] = worldSettings?.worldTemplateReferences?.length ? true : undefined; Telemetry_1.default.trackEvent({ name: TelemetryConstants_1.TelemetryEvents.CUSTOM_WORLD_DOWNLOADED, properties, }); await creatorTools.notifyOperationEnded(operId, "World + local assets generation for '" + targetFolder.fullPath + "' completed."); return mcworld; } static async deployProjectAndGeneratedWorldTo(creatorTools, project, worldSettings, deployFolder) { const operId = await creatorTools.notifyOperationStarted("Deploying project '" + project.name + "' plus world and test assets."); await project.ensureLoadedProjectFolder(); const worldFolderName = project.deployWorldId; const title = project.name + " Test World"; let targetFolder; if (deployFolder) { const worldsFolder = await ProjectExporter.ensureWorldsFolder(deployFolder); if (!worldsFolder) { Log_1.default.unexpectedUndefined("DPWATAD"); return; } targetFolder = worldsFolder.ensureFolder(worldFolderName); await targetFolder.ensureExists(); } else { const worldsFolder = await ProjectExporter.ensureMinecraftWorldsFolder(creatorTools); if (!worldsFolder) { Log_1.default.unexpectedUndefined("DPWATAE"); return; } targetFolder = worldsFolder.ensureFolder(worldFolderName); await targetFolder.ensureExists(); } const mcworld = await ProjectExporter.generateWorldWithPacks(creatorTools, project, worldSettings, targetFolder); if (mcworld) { await targetFolder.saveAll(); await mcworld.save(); } await project.save(); await creatorTools.notifyOperationEnded(operId, "World + local assets deploy to '" + targetFolder.fullPath + "' completed."); return title; } static async deployAsFlatPackRefWorld(creatorTools, project) { await creatorTools.notifyStatusUpdate("Saving..."); await ProjectExporter.updateProjects(project); await project.save(); await creatorTools.notifyStatusUpdate("Saved"); let deployTarget = creatorTools.defaultDeploymentTarget; // only do an explicit deploy here autodeployment is not turned on; otherwise, deployment should happen in the save() above. if ( // project.autoDeploymentMode !== ProjectAutoDeploymntMode.deployOnSave && deployTarget && deployTarget.deployBehaviorPacksFolder !== null && creatorTools.activeMinecraft) { await creatorTools.notifyStatusUpdate("Deploying pack add-ons"); creatorTools.activeMinecraft.syncWithDeployment(); await creatorTools.notifyStatusUpdate("Deployed"); } const hash = project.defaultBehaviorPackUniqueId + "|"; if ((project.lastMapDeployedHash === undefined || project.lastMapDeployedHash !== hash) && creatorTools.workingStorage !== null) { await ProjectExporter.generateAndInvokeFlatPackRefMCWorld(creatorTools, project); project.lastMapDeployedHash = hash; project.lastMapDeployedDate = new Date(); } } static async convertWorld(creatorTools, project, settings, world) { if (!world) { return; } if (creatorTools.workingStorage === null) { Log_1.default.fail("Did not find expected working storage."); return; } const dtNow = new Date(); const tempWorkingPathName = "WorldConvert" + Utilities_1.default.getDateStr(dtNow); const workingFolder = creatorTools.workingStorage.rootFolder.ensureFolder(tempWorkingPathName); await workingFolder.ensureExists(); if (world) { const inputFolder = workingFolder.ensureFolder("source-" + settings.name); await inputFolder.ensureExists(); await world.copyAsFolderTo(inputFolder); } const jsonContent = JSON.stringify(settings); await AppServiceProxy_1.default.sendAsync(AppServiceProxy_1.AppServiceProxyCommands.convertFile, jsonContent, true); await workingFolder.load(true); if (workingFolder.folderExists(settings.name)) { const outputFolder = workingFolder.ensureFolder(settings.name); const zs = new ZipStorage_1.default(); await StorageUtilities_1.default.syncFolderTo(outputFolder, zs.rootFolder, false, false, false); const resultBytes = await zs.generateCompressedUint8ArrayAsync(); return resultBytes; } return undefined; } static async syncFlatPackRefWorldTo(creatorTools, project, worldFolder, name) { if (creatorTools.workingStorage === null) { Log_1.default.fail("Did not find expected working storage."); return; } const mcworld = await ProjectExporter.generateFlatGameTestWorldWithPackRefs(project, name); if (mcworld !== undefined) { // Log.debugAlert("Synchronizing '" + worldFolder.name + "' with '" + worldFolder.files.length + "' files"); await mcworld.syncFolderTo(worldFolder); } else { Log_1.default.fail("Could not retrieve flat game test world"); } } static async generateAndInvokeFlatPackRefMCWorld(creatorTools, project) { if (creatorTools.workingStorage === null) { Log_1.default.fail("Did not find expected working storage."); return; } const fileName = project.name + " flatpack.mcworld"; const name = project.name + " Flat"; const mcworld = await ProjectExporter.generateFlatGameTestWorldWithPackRefs(project, name); if (mcworld !== undefined) { const newBytes = await mcworld.getBytes(); if (newBytes !== undefined) { const file = creatorTools.workingStorage.rootFolder.ensureFile(fileName); file.setContent(newBytes); await file.saveContent(); if (AppServiceProxy_1.default.hasAppService) { await AppServiceProxy_1.default.sendAsync(AppServiceProxy_1.AppServiceProxyCommands.shellOpenPath, file.fullPath); } } } } static async generateFlatGameTestWorldWithPackRefs(project, worldName) { await Database_1.default.loadContent(); if (Database_1.default.contentFolder === null) { Log_1.default.unexpectedContentState(); return undefined; } const file = Database_1.default.contentFolder.ensureFile("flatcreativegt.mcworld"); if (!file.isContentLoaded) { await file.loadContent(); } if (file.content instanceof Uint8Array) { const mcworld = await this.generateBetaApisWorldWithPackRefs(project, worldName, file.content); return mcworld; } Log_1.default.fail("Unexpectedly could not find default content."); return undefined; } static async generateMCAddonAsZip(creatorTools, project, returnAsBlob) { const operId = await creatorTools.notifyOperationStarted("Exporting '" + project.name + "' as MCPack"); const zipStorage = new ZipStorage_1.default(); const projectBuild = await ProjectExporter.prepareProject(project); if (!projectBuild) { return undefined; } await ProjectExporter.deployProjectPacks(project, projectBuild, zipStorage.rootFolder, undefined, 2 /* FolderDeploy.noFolders */); await zipStorage.rootFolder.saveAll(); if (returnAsBlob) { const zipBinary = await zipStorage.generateBlobAsync(); await creatorTools.notifyOperationEnded(operId, "Export MCPack of '" + project.name + "' created; downloading..."); return zipBinary; } else { const zipBytes = await zipStorage.generateUint8ArrayAsync(); return zipBytes; } } static async generateWorldWithPacksAndContent(project, worldName, worldContent, worldSettings) { await project.ensureLoadedProjectFolder(); const mcworld = new MCWorld_1.default(); if (worldContent) { mcworld.loadFromBytes(worldContent); } else if (!worldSettings) { const levelDat = mcworld.ensureLevelData(); levelDat.ensureDefaults(); } if (worldSettings) { mcworld.applyWorldSettings(worldSettings); } mcworld.project = project; const projectBuild = await ProjectExporter.prepareProject(project); if (!projectBuild) { return undefined; } await this.ensureExperimentsEnabledOnWorld(mcworld, project); mcworld.name = worldName; await ProjectExporter.deployProjectPacks(project, projectBuild, mcworld.storage.rootFolder, mcworld); return mcworld; } static async ensureExperimentsEnabledOnWorld(mcworld, project) { const itemsCopy = project.getItemsCopy(); for (const projectItem of itemsCopy) { if (projectItem.itemType === IProjectItemData_1.ProjectItemType.behaviorPackManifestJson) { if (!projectItem.isContentLoaded) { await projectItem.loadContent(); } const itemFile = projectItem.primaryFile; if (itemFile) { if (!itemFile.isContentLoaded) { await itemFile.loadContent(); } let content = itemFile.content; if (typeof content === "string" && content.indexOf("-beta") >= 0) { mcworld.betaApisExperiment = true; } } } else if (projectItem.itemType === IProjectItemData_1.ProjectItemType.resourcePackManifestJson) { if (!projectItem.isContentLoaded) { await projectItem.loadContent(); } const itemFile = projectItem.primaryFile; if (itemFile) { if (!itemFile.isContentLoaded) { await itemFile.loadContent(); } let content = itemFile.content; if (typeof content === "string" && content.indexOf("pbr") >= 0 && content.indexOf("capabilities") >= 0) { mcworld.deferredTechnicalPreviewExperiment = true; } } } } } static async generateBetaApisWorldWithPackRefs(project, worldName, worldContent) { const mcworld = new MCWorld_1.default(); mcworld.project = project; await mcworld.loadFromBytes(worldContent); const behaviorPackFolder = await project.getDefaultBehaviorPackFolder(); if (behaviorPackFolder !== null) { mcworld.ensureBehaviorPack(project.defaultBehaviorPackUniqueId, project.defaultBehaviorPackVersion, project.name); } const resourcePackFolder = await project.getDefaultResourcePackFolder(); if (resourcePackFolder !== null) { mcworld.ensureResourcePack(project.defaultResourcePackUniqueId, project.defaultResourcePackVersion, project.name); } mcworld.betaApisExperiment = true; mcworld.name = worldName; return mcworld; } } exports.default = ProjectExporter;