UNPKG

@minecraft/creator-tools

Version:

Minecraft Creator Tools command line and libraries.

1,205 lines (1,197 loc) 50.4 kB
"use strict"; // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. Object.defineProperty(exports, "__esModule", { value: true }); const axios_1 = require("axios"); const BlockType_1 = require("./BlockType"); const BlockBaseType_1 = require("./BlockBaseType"); const MinecraftUtilities_1 = require("./MinecraftUtilities"); const Log_1 = require("./../core/Log"); const HttpStorage_1 = require("../storage/HttpStorage"); const CartoApp_1 = require("./../app/CartoApp"); const Utilities_1 = require("../core/Utilities"); const NpmModule_1 = require("../devproject/NpmModule"); const ContentIndex_1 = require("../core/ContentIndex"); const Project_1 = require("../app/Project"); const IProjectItemData_1 = require("../app/IProjectItemData"); const StorageUtilities_1 = require("../storage/StorageUtilities"); const ICartoData_1 = require("../app/ICartoData"); const BlocksCatalogDefinition_1 = require("./BlocksCatalogDefinition"); const TerrainTextureCatalogDefinition_1 = require("./TerrainTextureCatalogDefinition"); const SoundDefinitionCatalogDefinition_1 = require("./SoundDefinitionCatalogDefinition"); const ItemTextureCatalogDefinition_1 = require("./ItemTextureCatalogDefinition"); const ZipStorage_1 = require("../storage/ZipStorage"); class Database { static get defaultBlockBaseType() { if (Database._defaultBlockBaseType === undefined) { Database._defaultBlockBaseType = Database.ensureBlockBaseType("block"); } return Database._defaultBlockBaseType; } static async ensureFormLoadedByPath(path) { const lastSlash = path.lastIndexOf("/"); if (lastSlash >= 0) { return await Database.ensureFormLoaded(path.substring(0, lastSlash), path.substring(lastSlash + 1)); } return undefined; } static async ensureFormLoaded(subFolder, name) { name = name.toLowerCase(); if (Database.uxCatalog[name] !== undefined) { return Database.uxCatalog[name]; } let path = CartoApp_1.default.contentRoot + "data/forms/"; if (subFolder) { path += subFolder + "/"; } if (Database.local) { const storage = await Database.local.createStorage(path); if (storage) { await storage.rootFolder.load(); const file = storage.rootFolder.files[name + ".form.json"]; if (file) { await file.loadContent(); return StorageUtilities_1.default.getJsonObject(file); } Log_1.default.fail("Could not load file locally for '" + (subFolder ? subFolder + "/" : "") + name + "'."); return undefined; } } else { try { const response = await axios_1.default.get(path + name + ".form.json"); Database.uxCatalog[(subFolder ? subFolder + "." : "") + name] = response.data; Database.loadedFormCount++; return response.data; } catch { Log_1.default.fail("Could not load UX file for '" + (subFolder ? subFolder + "/" : "") + name + "'."); } } return undefined; } static async getFormsFolder(subFolder) { if (this.formsFolders[subFolder]) { return this.formsFolders[subFolder]; } const folderPath = "data/forms/" + subFolder + "/"; if (Database.local) { const storage = await Database.local.createStorage(folderPath); if (storage) { await storage.rootFolder.load(); this.formsFolders[subFolder] = storage.rootFolder; } } else { const storage = new HttpStorage_1.default(CartoApp_1.default.contentRoot + folderPath); await storage.rootFolder.load(); this.formsFolders[subFolder] = storage.rootFolder; } return this.formsFolders[subFolder]; } static getFormByPath(path) { const lastSlash = path.lastIndexOf("/"); if (lastSlash >= 0) { return Database.getForm(path.substring(0, lastSlash), path.substring(lastSlash + 1)); } return undefined; } static getForm(subFolder, name) { name = name.toLowerCase(); return Database.uxCatalog[(subFolder ? subFolder + "." : "") + name]; } static getBlockType(name) { name = MinecraftUtilities_1.default.canonicalizeName(name); const blockType = Database.blockTypes[name]; return blockType; } static populateBlockTypesByLegacyId() { this._blockTypesByLegacyId = []; for (const blockTypeName in this.blockTypes) { const blockType = this.blockTypes[blockTypeName]; if (blockType.numericId !== undefined) { Log_1.default.assert(this._blockTypesByLegacyId[blockType.numericId] === undefined, "Multiple block types registered for the same ID:" + blockType.id); this._blockTypesByLegacyId[blockType.numericId] = blockType; } } } static async getModuleDescriptor(moduleId) { if (Database.moduleDescriptors[moduleId]) { return Database.moduleDescriptors[moduleId]; } try { const response = await axios_1.default.get("https://registry.npmjs.org/" + moduleId); Database.moduleDescriptors[moduleId] = new NpmModule_1.default(response.data); } catch { Log_1.default.fail("Could not load registry for '" + moduleId + "'"); } return Database.moduleDescriptors[moduleId]; } static async getLatestMinecraftRetailVersion() { const moduleDescriptor = await this.getModuleDescriptor("@minecraft/server"); if (!moduleDescriptor || !moduleDescriptor.latestRetailVersion) { return "1.21.0"; } return moduleDescriptor.latestRetailVersion; } static async isRecentVersionFromVersionArray(version) { if (version === undefined || version.length !== 3) { return false; } const ver = await this.getLatestVersionInfo(ICartoData_1.MinecraftTrack.main); if (!ver) { return false; } const verArr = MinecraftUtilities_1.default.getVersionArrayFrom(ver); if (!verArr || verArr.length < 3) { return false; } const majorVersion = verArr[0]; const minorVersion = verArr[1]; if (version[0] < majorVersion) { return false; } if (majorVersion === version[0] && minorVersion - version[1] > 1) { return false; } return true; } static async ensureCreatorToolsIngameProject() { if (Database._creatorToolsIngameProject) { return Database._creatorToolsIngameProject; } await Database.loadContent(); if (Database.contentFolder === null || !CartoApp_1.default.carto) { Log_1.default.unexpectedContentState(); return undefined; } const file = Database.contentFolder.ensureFile("creator_tools_ingame.mcaddon"); await file.loadContent(); if (file.content instanceof Uint8Array) { Database._creatorToolsIngameProject = new Project_1.default(CartoApp_1.default.carto, "Creator Tools", null); const projectFolder = await Database._creatorToolsIngameProject.ensureProjectFolder(); const folder = projectFolder.ensureFolder("addons"); const contentFile = folder.ensureFile(file.name); contentFile.setContent(file.content); contentFile.saveContent(); const relPath = contentFile.getFolderRelativePath(Database._creatorToolsIngameProject.projectFolder); if (relPath !== undefined) { Database._creatorToolsIngameProject.ensureItemByProjectPath(relPath, IProjectItemData_1.ProjectItemStorageType.singleFile, file.name, IProjectItemData_1.ProjectItemType.MCAddon, undefined, IProjectItemData_1.ProjectItemCreationType.normal); await Database._creatorToolsIngameProject.inferProjectItemsFromZipFile(relPath, contentFile, false); } return Database._creatorToolsIngameProject; } return undefined; } static async getLatestVersionInfo(track, force) { if (track === ICartoData_1.MinecraftTrack.edu) { return Database.minecraftEduVersion; } if (track === ICartoData_1.MinecraftTrack.eduPreview) { return Database.minecraftEduPreviewVersion; } if (track === ICartoData_1.MinecraftTrack.preview && Database.latestPreviewVersion && !force) { return Database.latestPreviewVersion; } if (track === ICartoData_1.MinecraftTrack.main && Database.latestVersion && !force) { return Database.latestVersion; } let minecraftInfoResponse = undefined; let versionUrl = "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/version.json"; if (track === ICartoData_1.MinecraftTrack.preview) { versionUrl = "https://raw.githubusercontent.com/Mojang/bedrock-samples/preview/version.json"; } try { minecraftInfoResponse = await axios_1.default.get(versionUrl); } catch (e) { console.log("Could not access Minecraft version details." + e); throw new Error(e.toString()); } let latestVersionIndex = 0; let latestVerStr = ""; try { if (minecraftInfoResponse === undefined || minecraftInfoResponse.data === undefined) { throw new Error("Unexpected empty response."); } const responseJson = JSON.parse(JSON.stringify(minecraftInfoResponse.data)); if (!responseJson) { throw new Error("Improperly formatted response (source: " + minecraftInfoResponse.data + ")"); } for (const verId in responseJson) { const ver = responseJson[verId].version; if (ver) { const isPreview = Database.getVersionIsPreview(ver); // version ends with .20 or higher const versionIndex = Database.getVersionIndexFromVersionStr(ver); if (versionIndex > 0 && versionIndex > latestVersionIndex && ((isPreview && track === ICartoData_1.MinecraftTrack.preview) || (!isPreview && track === ICartoData_1.MinecraftTrack.main))) { latestVersionIndex = versionIndex; // re-constitute the version number ourselves const verNums = ver.split("."); latestVerStr = verNums[0] + "." + verNums[1] + "." + verNums[2] + "." + Utilities_1.default.frontPadToLength(verNums[3], 2, "0"); } } } } catch (e) { Log_1.default.error("Could not process Minecraft version details." + e); throw new Error(e.toString()); } if (latestVerStr && latestVerStr.length > 0) { if (track === ICartoData_1.MinecraftTrack.preview) { Database.latestPreviewVersion = latestVerStr; } else { Database.latestVersion = latestVerStr; } } return latestVerStr; } static getVersionIsPreview(ver) { const verNums = ver.split("."); if (verNums.length !== 4) { return false; } for (let j = 0; j < verNums.length; j++) { if (!Utilities_1.default.isNumeric(verNums[j])) { return false; } } return parseInt(verNums[3]) > 19; } static getVersionIndexFromVersionStr(ver) { const verNums = ver.split("."); if (verNums.length !== 4) { return -1; } for (let j = 0; j < verNums.length; j++) { if (!Utilities_1.default.isNumeric(verNums[j])) { return -1; } } const versionIndex = parseInt(verNums[0]) * 16777216 + parseInt(verNums[1]) * 65536 + parseInt(verNums[2]) * 256 + parseInt(verNums[3]); return versionIndex; } static getBlockTypeByLegacyId(id) { if (!this._blockTypesByLegacyId) { this._blockTypesByLegacyId = []; this.populateBlockTypesByLegacyId(); } const result = this._blockTypesByLegacyId[id]; // Log.assert(result !== undefined); return result; } static getMatchingBlocks(searchTerm) { searchTerm = searchTerm.toLowerCase().trim(); searchTerm = searchTerm.replace(/_/gi, " "); const searchTerms = searchTerm.split(" "); let exactMatch = undefined; let matches = []; for (const name in this.blockTypes) { const bt = this.blockTypes[name]; const titleCanon = bt.title.toLowerCase(); if (titleCanon === searchTerm && exactMatch === undefined) { exactMatch = bt; } else { for (let i = 0; i < searchTerms.length; i++) { if (titleCanon.indexOf(searchTerms[i]) >= 0) { matches.push(bt); break; } } } } if (exactMatch !== undefined) { const newMatches = [exactMatch]; for (let i = 0; i < matches.length; i++) { newMatches.push(matches[i]); } matches = newMatches; } return matches; } static ensureBlockType(name) { name = MinecraftUtilities_1.default.canonicalizeName(name); let blockType = Database.blockTypes[name]; if (blockType == null && Database.catalog != null) { blockType = new BlockType_1.default(name); Database.blockTypes[name] = blockType; blockType.data = { name: name, }; } return blockType; } static ensureBlockBaseType(name) { name = MinecraftUtilities_1.default.canonicalizeName(name); let blockBaseType = Database.blockBaseTypes[name]; if (blockBaseType == null) { blockBaseType = new BlockBaseType_1.default(name); Database.blockBaseTypes[name] = blockBaseType; } return blockBaseType; } static async loadContent() { if (Database.contentFolder !== null) { return; } if (Database.local) { const storage = await Database.local.createStorage("data/content/"); if (storage) { await storage.rootFolder.load(); Database.contentFolder = storage.rootFolder; } } else { const storage = new HttpStorage_1.default(CartoApp_1.default.contentRoot + "data/content/"); await storage.rootFolder.load(); Database.contentFolder = storage.rootFolder; } } static async initSnippetsFolder() { if (Database.snippetsFolder !== null) { return; } if (this._isLoadingSnippets) { const pendingLoad = this._pendingLoadSnippetsRequests; const prom = (resolve, reject) => { pendingLoad.push(resolve); }; await new Promise(prom); return; } else { this._isLoadingSnippets = true; let folder; if (Database.local) { const storage = await Database.local.createStorage("data/snippets/"); if (storage) { folder = storage.rootFolder; } } else { const storage = new HttpStorage_1.default(CartoApp_1.default.contentRoot + "data/snippets/"); folder = storage.rootFolder; } if (folder === undefined) { return; } await folder.load(); for (const fileName in folder.files) { const file = folder.files[fileName]; if (file) { await file.loadContent(); } } Database.snippetsFolder = folder; this._isLoadingSnippets = false; const pendingLoad = this._pendingLoadSnippetsRequests; this._pendingLoadSnippetsRequests = []; for (const prom of pendingLoad) { prom(undefined); } } } static itemMatchesSearch(item, searchString) { if (!searchString || searchString.length < 3) { return true; } const searchKey = searchString.toLowerCase(); if ((item.title && item.title.toLowerCase().indexOf(searchKey) >= 0) || (item.description && item.description.toLowerCase().indexOf(searchKey) >= 0)) { return true; } if (item.topics) { for (const topic of item.topics) { if (topic.toLowerCase().indexOf(searchKey) >= 0) { return true; } } } return false; } static async getSnippet(sampleSet, snippetId) { if (!Database.snippetsFolder) { await Database.initSnippetsFolder(); } if (!Database.snippetsFolder) { return undefined; } if (Database.snippetsFolder !== null && Database.snippetsFolder.files) { const file = Database.snippetsFolder.files[sampleSet + ".json"]; if (file) { const snipSet = StorageUtilities_1.default.getJsonObject(file); if (snipSet && snipSet[snippetId]) { return snipSet[snippetId]; } } } return undefined; } static async getAddonsDocs() { if (!Database.addonsDocs) { Database.addonsDocs = await Database.getMetadataObject("/doc_modules/addons.json"); } return Database.addonsDocs; } static async getBiomesMetadata() { if (!Database.biomesMetadata) { Database.biomesMetadata = await Database.getMetadataObject("/vanilladata_modules/mojang-biomes.json"); } return Database.biomesMetadata; } static getVanillaBlocksCatalogDirect() { return this.blocksCatalog; } static async getVanillaBlocksCatalog() { if (!Database.blocksCatalog) { const file = await Database.getPreviewVanillaFile("/resource_pack/blocks.json"); if (file) { const blockCat = new BlocksCatalogDefinition_1.default(); blockCat.file = file; await blockCat.load(); this.blocksCatalog = blockCat; } } return this.blocksCatalog; } static getVanillaTerrainTexturesCatalogDirect() { return this.terrainTextureCatalog; } static async getVanillaTerrainTexturesCatalog() { if (!Database.terrainTextureCatalog) { const file = await Database.getPreviewVanillaFile("/resource_pack/textures/terrain_texture.json"); if (file) { const terrainCat = new TerrainTextureCatalogDefinition_1.default(); terrainCat.file = file; await terrainCat.load(); Database.terrainTextureCatalog = terrainCat; } } return Database.terrainTextureCatalog; } static async getVanillaItemTexturesCatalog() { if (!Database.itemTextureCatalog) { const file = await Database.getPreviewVanillaFile("/resource_pack/textures/item_texture.json"); if (file) { const itemCat = new ItemTextureCatalogDefinition_1.default(); itemCat.file = file; await itemCat.load(); Database.itemTextureCatalog = itemCat; } } return Database.itemTextureCatalog; } static async getVanillaSoundDefinitionCatalog() { if (!Database.soundDefinitionCatalog) { const file = await Database.getPreviewVanillaFile("/resource_pack/sounds/sound_definitions.json"); if (file) { const soundDefinitionCat = new SoundDefinitionCatalogDefinition_1.default(); soundDefinitionCat.file = file; await soundDefinitionCat.load(); Database.soundDefinitionCatalog = soundDefinitionCat; } } return Database.soundDefinitionCatalog; } static async getBlocksMetadata() { if (!Database.blocksMetadata) { Database.blocksMetadata = await Database.getMetadataObject("/vanilladata_modules/mojang-blocks.json"); } return Database.blocksMetadata; } static async getEntitiesMetadata() { if (!Database.entitiesMetadata) { Database.entitiesMetadata = await Database.getMetadataObject("/vanilladata_modules/mojang-entities.json"); } return Database.entitiesMetadata; } static async getItemsMetadata() { if (!Database.itemsMetadata) { Database.itemsMetadata = await Database.getMetadataObject("/vanilladata_modules/mojang-items.json"); } return Database.itemsMetadata; } static async getMetadataObject(metaPath) { await Database.loadPreviewMetadataFolder(); if (!Database.previewMetadataFolder) { return null; } const jsonFile = await Database.previewMetadataFolder.getFileFromRelativePath(metaPath); if (!jsonFile) { Log_1.default.unexpectedUndefined(); return null; } await jsonFile.loadContent(); const jsonObj = StorageUtilities_1.default.getJsonObject(jsonFile); if (!jsonObj) { Log_1.default.unexpectedUndefined(); return null; } return jsonObj; } static async getPreviewVanillaFile(filePath) { const vanillaFolder = await Database.getPreviewVanillaFolder(); if (!vanillaFolder) { return null; } const jsonFile = await vanillaFolder.getFileFromRelativePath(filePath); if (!jsonFile) { Log_1.default.unexpectedUndefined(); return null; } await jsonFile.loadContent(); return jsonFile; } static async getPreviewVanillaObject(filePath) { const jsonFile = await Database.getPreviewVanillaFile(filePath); if (!jsonFile) { Log_1.default.unexpectedUndefined(); return null; } const jsonObj = StorageUtilities_1.default.getJsonObject(jsonFile); if (!jsonObj) { Log_1.default.unexpectedUndefined(); return null; } return jsonObj; } static async loadPreviewMetadataFolder() { if (!this.previewMetadataFolder) { if (Database.local) { const storage = await Database.local.createStorage("res/latest/van/preview/metadata/"); if (storage) { this.previewMetadataFolder = storage.rootFolder; } } else { const metadataStorage = new HttpStorage_1.default(CartoApp_1.default.contentRoot + "res/latest/van/preview/metadata/"); await metadataStorage.rootFolder.load(); this.previewMetadataFolder = metadataStorage.rootFolder; } } return this.previewMetadataFolder; } static async loadReleaseMetadataFolder() { if (!this.releaseMetadataFolder) { if (Database.local) { const storage = await Database.local.createStorage("res/latest/van/release/metadata/"); if (storage) { this.releaseMetadataFolder = storage.rootFolder; } } else { const metadataStorage = new HttpStorage_1.default(CartoApp_1.default.contentRoot + "res/latest/van/release/metadata/"); await metadataStorage.rootFolder.load(); this.releaseMetadataFolder = metadataStorage.rootFolder; } } return this.releaseMetadataFolder; } static async getReleaseVanillaFolder() { if (Database.releaseVanillaFolder !== null) { return Database.releaseVanillaFolder; } if (Database.local) { const storage = await Database.local.createStorage("res/latest/van/release/"); if (storage) { Database.releaseVanillaFolder = storage.rootFolder; } } else { const storage = new HttpStorage_1.default(CartoApp_1.default.contentRoot + "res/latest/van/release/"); Database.releaseVanillaFolder = storage.rootFolder; } if (Database.releaseVanillaFolder) { await Database.releaseVanillaFolder.load(); } return Database.releaseVanillaFolder; } static async getPreviewVanillaFolder() { if (Database.previewVanillaFolder !== null) { return Database.previewVanillaFolder; } if (Database.local) { const storage = await Database.local.createStorage("res/latest/van/preview/"); if (storage) { Database.previewVanillaFolder = storage.rootFolder; } } else { const storage = new HttpStorage_1.default(CartoApp_1.default.contentRoot + "res/latest/van/preview/"); Database.previewVanillaFolder = storage.rootFolder; } if (Database.previewVanillaFolder) { await Database.previewVanillaFolder.load(); } return Database.previewVanillaFolder; } static async getSamplesFolder() { if (Database.samplesFolder !== null) { return Database.samplesFolder; } if (Database.local) { const storage = await Database.local.createStorage("res/samples/microsoft/minecraft-samples-main/"); if (storage) { Database.samplesFolder = storage.rootFolder; } } else { const storage = new HttpStorage_1.default(CartoApp_1.default.contentRoot + "res/samples/microsoft/minecraft-samples-main/"); Database.samplesFolder = storage.rootFolder; } if (Database.samplesFolder) { await Database.samplesFolder.load(); } return Database.samplesFolder; } static async getReleaseVanillaBehaviorPackFolder() { if (Database.releaseVanillaBehaviorPackFolder !== null) { return Database.releaseVanillaBehaviorPackFolder; } if (Database.local) { const storage = await Database.local.createStorage("res/latest/van/release/behavior_pack/"); if (storage) { Database.releaseVanillaBehaviorPackFolder = storage.rootFolder; } } else { const storage = new HttpStorage_1.default(CartoApp_1.default.contentRoot + "res/latest/van/release/behavior_pack/"); Database.releaseVanillaBehaviorPackFolder = storage.rootFolder; } if (Database.releaseVanillaBehaviorPackFolder) { await Database.releaseVanillaBehaviorPackFolder.load(); } return Database.releaseVanillaBehaviorPackFolder; } static async getReleaseVanillaResourcePackFolder() { if (Database.releaseVanillaResourcePackFolder !== null) { return Database.releaseVanillaResourcePackFolder; } if (Database.local) { const storage = await Database.local.createStorage("res/latest/van/release/resource_pack/"); if (storage) { Database.releaseVanillaResourcePackFolder = storage.rootFolder; } } else { const storage = new HttpStorage_1.default(CartoApp_1.default.contentRoot + "res/latest/van/release/resource_pack/"); Database.releaseVanillaResourcePackFolder = storage.rootFolder; } if (Database.releaseVanillaResourcePackFolder) { await Database.releaseVanillaResourcePackFolder.load(); } return Database.releaseVanillaResourcePackFolder; } static async loadUx() { } static getComponentFormField(propertyName) { if (Database.uxCatalog === undefined || Database.uxCatalog === null) { Log_1.default.unexpectedNull(); return undefined; } throw new Error("Not implemented."); /* const componentForms = Database.uxCatalog.forms; for (const formName in componentForms) { const form = componentForms[formName]; if (form === undefined) { break; } for (let i = 0; i < form.fields.length; i++) { const field = form.fields[i]; if (field.id === propertyName || field.altId === propertyName) { return { form: form, field: field, }; } } } */ } static async getSchema(path) { path = path.toLowerCase(); if (Database.schemaContents[path]) { return Database.schemaContents[path]; } const schemaPath = "/" + Database.dataPath + "schemas/" + path; try { // @ts-ignore if (typeof window !== "undefined") { const response = await axios_1.default.get(Utilities_1.default.ensureEndsWithSlash(CartoApp_1.default.contentRoot) + Utilities_1.default.ensureNotStartsWithSlash(schemaPath)); Database.schemaContents[path] = response.data; if (!Database.schemaContents[path]) { Log_1.default.fail("Could not load schema '" + schemaPath + "'"); } return Database.schemaContents[path]; } else if (Database.local) { const result = await Database.local.readJsonFile(schemaPath); if (result !== null) { Database.schemaContents[path] = result; return Database.schemaContents[path]; } else { Log_1.default.fail("Could not load schema '" + schemaPath + "'"); return undefined; } } else { Log_1.default.fail("Unexpected database config (no database available) when trying to load schema for:" + path); return undefined; } } catch (e) { Log_1.default.fail("Could not load Minecraft schema catalog: " + CartoApp_1.default.contentRoot + " - " + schemaPath + " " + e.toString()); return undefined; } } static async loadBetaScriptTypes() { if (Database.betaTypeDefs) { return; } try { // @ts-ignore if (typeof window !== "undefined") { const response = await axios_1.default.get(CartoApp_1.default.contentRoot + "data/typedefs.beta.json"); Database.betaTypeDefs = response.data; } else if (Database.local) { const result = await Database.local.readJsonFile("data/typedefs.beta.json"); if (result !== null) { Database.betaTypeDefs = result; } } } catch { Log_1.default.fail("Could not load beta Minecraft types catalog."); } } static async loadStableScriptTypes() { if (Database.stableTypeDefs) { return; } try { // @ts-ignore if (typeof window !== "undefined") { const response = await axios_1.default.get(CartoApp_1.default.contentRoot + "data/typedefs.stable.json"); Database.stableTypeDefs = response.data; } else if (Database.local) { const result = await Database.local.readJsonFile("data/typedefs.stable.json"); if (result !== null) { Database.stableTypeDefs = result; } } } catch { Log_1.default.fail("Could not load stable Minecraft types catalog."); } } static async getLibs() { if (Database.libs) { return Database.libs; } try { // @ts-ignore if (typeof window !== "undefined") { const response = await axios_1.default.get(CartoApp_1.default.contentRoot + "data/libs.json"); Database.libs = response.data; } else if (Database.local) { const result = await Database.local.readJsonFile("data/libs.json"); if (result !== null) { Database.libs = result; } } } catch { Log_1.default.fail("Could not load libraries catalog."); } return Database.libs; } static async matchesVanillaPath(path) { const rpFolder = await Database.getReleaseVanillaResourcePackFolder(); if (rpFolder && rpFolder.folderCount > 0) { path = Utilities_1.default.ensureStartsWithSlash(path); const folder = await rpFolder.getFolderFromRelativePath(StorageUtilities_1.default.getFolderPath(path)); if (!folder) { return false; } const exists = await folder.exists(); if (!exists) { return false; } const itemName = StorageUtilities_1.default.getBaseFromName(StorageUtilities_1.default.getLeafName(path)).toLowerCase(); await folder.load(); for (let fileName in folder.files) { if (fileName && StorageUtilities_1.default.getBaseFromName(fileName).toLowerCase() === itemName) { return true; } } } else { let res = await Database.matchesVanillaPathFromIndex(path); return res; } return false; } static async matchesVanillaPathFromIndex(path) { if (!Database.vanillaContentIndex) { await this.loadVanillaInfoData(); } if (!Database.vanillaContentIndex) { return false; } let result = Database.vanillaContentIndex.hasPathMatches(path); if (!result) { result = await Database.isVanillaToken(path); } if (!result) { if (!path.startsWith("/resource_pack/") && path.startsWith("/")) { result = Database.vanillaContentIndex.hasPathMatches("/resource_pack" + path); if (!result) { result = await Database.isVanillaToken("/resource_pack" + path); if (!result) { if (!path.startsWith("/behavior_pack/")) { result = Database.vanillaContentIndex.hasPathMatches("/behavior_pack" + path); if (!result) { result = await Database.isVanillaToken("/behavior_pack" + path); } } } } } } return result; } static async isVanillaToken(path) { const matches = await Database.getVanillaMatches(path, true); if (matches && matches.length > 0) { return true; } return false; } static async getVanillaAll(withAnnotation) { if (!Database.vanillaContentIndex) { await this.loadVanillaInfoData(); } if (!Database.vanillaContentIndex) { return undefined; } return Database.vanillaContentIndex.getAll(withAnnotation); } static async getVanillaMatches(path, wholeTermSearch, withAnnotation) { if (!Database.vanillaContentIndex) { await this.loadVanillaInfoData(); } if (!Database.vanillaContentIndex) { return undefined; } return await Database.vanillaContentIndex.getMatches(path, wholeTermSearch, withAnnotation); } static async getPreviewVanillaMatches(path, wholeTermSearch, withAnnotation) { if (!Database.previewVanillaContentIndex) { await this.loadPreviewVanillaInfoData(); } if (!Database.previewVanillaContentIndex) { return undefined; } return await Database.previewVanillaContentIndex.getMatches(path, wholeTermSearch, withAnnotation); } static async getSamplesMatches(path, wholeTermSearch, withAnnotation) { if (!Database.samplesContentIndex) { await this.loadSampleInfoData(); } if (!Database.samplesContentIndex) { return undefined; } return await Database.samplesContentIndex.getMatches(path, wholeTermSearch, withAnnotation); } static async loadVanillaInfoData() { if (Database.vanillaInfoData) { return; } if (this._isLoadingVanilla) { const pendingLoad = this._pendingLoadVanillaRequests; const prom = (resolve, reject) => { pendingLoad.push(resolve); }; await new Promise(prom); } else { this._isLoadingVanilla = true; try { // @ts-ignore if (typeof window !== "undefined") { const response = await axios_1.default.get(CartoApp_1.default.contentRoot + "data/mci/release.mci.json.zip", { responseType: "arraybuffer", headers: { Accept: "application/octet-stream, application/json, text/plain, */*", }, }); if (response) { Database.vanillaInfoData = await ZipStorage_1.default.fromZipBytesToJsonObject(response.data); } } else if (Database.local) { const result = await Database.local.readJsonFile("data/mci/release.mci.json"); if (result !== null) { Database.vanillaInfoData = result; } } if (Database.vanillaInfoData && Database.vanillaInfoData.index && !Database.vanillaContentIndex) { Database.vanillaContentIndex = new ContentIndex_1.default(); Database.vanillaContentIndex.loadFromData(Database.vanillaInfoData.index); } } catch { // Log.fail("Could not load vanilla metadata."); } this._isLoadingVanilla = false; const pendingLoad = this._pendingLoadVanillaRequests; this._pendingLoadVanillaRequests = []; for (const prom of pendingLoad) { prom(undefined); } } } static async loadPreviewVanillaInfoData() { if (Database.previewVanillaContentIndex) { return; } if (this._isLoadingPreviewVanilla) { const pendingLoad = this._pendingLoadPreviewVanillaRequests; const prom = (resolve, reject) => { pendingLoad.push(resolve); }; await new Promise(prom); } else { this._isLoadingPreviewVanilla = true; try { // @ts-ignore if (typeof window !== "undefined") { const response = await axios_1.default.get(CartoApp_1.default.contentRoot + "data/mci/preview.mci.json.zip", { responseType: "arraybuffer", headers: { Accept: "application/octet-stream, application/json, text/plain, */*", }, }); if (response) { Database.previewVanillaInfoData = await ZipStorage_1.default.fromZipBytesToJsonObject(response.data); } } else if (Database.local) { const result = await Database.local.readJsonFile("data/mci/preview.mci.json"); if (result !== null) { Database.previewVanillaInfoData = result; } } if (Database.previewVanillaInfoData && Database.previewVanillaInfoData.index && !Database.previewVanillaContentIndex) { Database.previewVanillaContentIndex = new ContentIndex_1.default(); Database.previewVanillaContentIndex.loadFromData(Database.previewVanillaInfoData.index); } } catch { // Log.fail("Could not load preview vanilla metadata."); } this._isLoadingVanilla = false; const pendingLoad = this._pendingLoadPreviewVanillaRequests; this._pendingLoadPreviewVanillaRequests = []; for (const prom of pendingLoad) { prom(undefined); } } } static async loadSampleInfoData() { if (Database.samplesContentIndex) { return; } if (this._isLoadingSamples) { const pendingLoad = this._pendingLoadSamplesRequests; const prom = (resolve, reject) => { pendingLoad.push(resolve); }; await new Promise(prom); } else { this._isLoadingSamples = true; try { // @ts-ignore if (typeof window !== "undefined") { const response = await axios_1.default.get(CartoApp_1.default.contentRoot + "data/mci/minecraft-samples-main.mci.json"); Database.samplesInfoData = response.data; } else if (Database.local) { const result = await Database.local.readJsonFile("data/mci/minecraft-samples-main.mci.json"); if (result !== null) { Database.samplesInfoData = result; } } if (Database.samplesInfoData && Database.samplesInfoData.index && !Database.samplesContentIndex) { Database.samplesContentIndex = new ContentIndex_1.default(); Database.samplesContentIndex.loadFromData(Database.samplesInfoData.index); } } catch { // Log.fail("Could not load preview vanilla metadata."); } this._isLoadingSamples = false; const pendingLoad = this._pendingLoadSamplesRequests; this._pendingLoadSamplesRequests = []; for (const prom of pendingLoad) { prom(undefined); } } } static async load() { if (Database.isLoaded) { return; } try { // @ts-ignore if (typeof window !== "undefined") { const response = await axios_1.default.get(CartoApp_1.default.contentRoot + "data/mccat.json"); Database.catalog = response.data; } else if (Database.local) { const result = await Database.local.readJsonFile("data/mccat.json"); if (result !== null) { Database.catalog = result; // Log.debugAlert("Loaded catalog: " + Database.catalog.blockBaseTypes.length); } } if (Database.catalog !== null) { for (let i = 0; i < Database.catalog.blockBaseTypes.length; i++) { const blockBaseTypeData = Database.catalog.blockBaseTypes[i]; const baseTypeName = MinecraftUtilities_1.default.canonicalizeName(blockBaseTypeData.name); const blockBaseType = new BlockBaseType_1.default(baseTypeName); blockBaseType.data = blockBaseTypeData; if (blockBaseTypeData.abstract === undefined || blockBaseTypeData.abstract === false) { const newBlockType = { name: blockBaseTypeData.name, id: blockBaseTypeData.id, icon: blockBaseTypeData.icon, mapColor: blockBaseTypeData.mapColor, shortId: blockBaseTypeData.shortId, altShortId: blockBaseTypeData.altShortId, }; const blockType = this.ensureBlockType(baseTypeName); blockType.data = newBlockType; blockType.baseType = blockBaseType; } if (blockBaseTypeData.variants !== undefined) { for (let j = 0; j < blockBaseTypeData.variants.length; j++) { const variantBlockTypeData = blockBaseTypeData.variants[j]; const blockType = this.ensureBlockType(variantBlockTypeData.name); if (!variantBlockTypeData.id && blockBaseTypeData.id) { variantBlockTypeData.id = blockBaseTypeData.id; } if (!variantBlockTypeData.icon && blockBaseTypeData.icon) { variantBlockTypeData.icon = blockBaseTypeData.icon; } if (!variantBlockTypeData.shortId && blockBaseTypeData.shortId) { variantBlockTypeData.shortId = blockBaseTypeData.shortId; } if (!variantBlockTypeData.altShortId && blockBaseTypeData.altShortId) { variantBlockTypeData.altShortId = blockBaseTypeData.altShortId; } if (!variantBlockTypeData.mapColor && blockBaseTypeData.mapColor) { variantBlockTypeData.mapColor = blockBaseTypeData.mapColor; } blockType.data = variantBlockTypeData; blockType.baseType = blockBaseType; } } } } } catch { Log_1.default.fail("Could not load Minecraft types catalog."); } /* try { // @ts-ignore if (typeof window !== "undefined") { const response = await axios.get(CartoApp.contentRoot + "data/javacat.json"); Database.javaBlockTypeData = response.data; } else if (Database.local) { const result = await Database.local.readJsonFile("data/javacat.json"); if (result !== null) { Database.javaBlockTypeData = result as { [id: string]: IJavaBlockTypeData }; } } if (Database.javaBlockTypeData) { for (const blockName in Database.javaBlockTypeData) { const jtnBlock = Database.javaBlockTypeData[blockName]; jtnBlock.source = blockName; this.ensureBlockType(blockName).javaData = jtnBlock; } } Database.isLoaded = true; } catch { Log.fail("Could not load java catalog."); }*/ } } exports.default = Database; Database.isLoaded = false; Database.isScriptTypesLoaded = false; Database.catalog = null; Database.loadedFormCount = 0; Database._creatorToolsIngameProject = null; Database.uxCatalog = {}; Database.formsFolders = {}; Database.betaTypeDefs = null; Database.libs = null; Database.stableTypeDefs = null; Database.contentFolder = null; Database.snippetsFolder = null; Database.previewMetadataFolder = null; Database.releaseMetadataFolder = null; Database.previewVanillaFolder = null; Database.releaseVanillaFolder = null; Database.samplesFolder = null; Database.releaseVanillaBehaviorPackFolder = null; Database.releaseVanillaResourcePackFolder = null; Database.local = null; Database.vanillaInfoData = null; Database.vanillaContentIndex = null; Database.previewVanillaInfoData = null; Database.previewVanillaContentIndex = null; Database.samplesInfoData = null; Database.samplesContentIndex = null; Database.addonsDocs = null; Database.biomesMetadata = null; Database.blocksMetadata = null; Database.entitiesMetadata = null; Database.itemsMetadata = null; Database.blocksCatalog = null; Database.itemTextureCatalog = null; Database.terrainTextureCatalog = null; Database.soundDefinitionCatalog = null; Database._isLoadingSnippets = false; Database._pendingLoadSnippetsRequests = []; Database._isLoadingVanilla = false; Database._pendingLoadVanillaRequests = []; Database._isLoadingPreviewVanilla = false; Database._pendingLoadPreviewVanillaRequests = []; Database._isLoadingSamples = false; Database._pendingLoadSamplesRequests = []; Database.dataPath = "res/latest/"; Database.minecraftEduVersion = "1.21.0"; Database.minecraftEduPreviewVersion = "1.21.0"; Database.minecraftModuleNames = [ "@minecraft/server-gametest", "@minecraft/server", "@minecraft