@minecraft/creator-tools
Version:
Minecraft Creator Tools command line and libraries.
761 lines (760 loc) • 36.8 kB
JavaScript
"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;