@minecraft/creator-tools
Version:
Minecraft Creator Tools command line and libraries.
953 lines • 57 kB
JavaScript
"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