UNPKG

@minecraft/creator-tools

Version:

Minecraft Creator Tools command line and libraries.

389 lines (388 loc) 19.5 kB
"use strict"; // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.TextureInfoGeneratorTest = void 0; const ProjectInfoItem_1 = __importDefault(require("./ProjectInfoItem")); const IProjectItemData_1 = require("../app/IProjectItemData"); const IInfoItemData_1 = require("./IInfoItemData"); const EntityTypeResourceDefinition_1 = __importDefault(require("../minecraft/EntityTypeResourceDefinition")); const BlocksCatalogDefinition_1 = __importDefault(require("../minecraft/BlocksCatalogDefinition")); const TerrainTextureCatalogDefinition_1 = __importDefault(require("../minecraft/TerrainTextureCatalogDefinition")); const ParticleEffectResourceDefinition_1 = __importDefault(require("../minecraft/ParticleEffectResourceDefinition")); const ItemTextureCatalogDefinition_1 = __importDefault(require("../minecraft/ItemTextureCatalogDefinition")); const AttachableResourceDefinition_1 = __importDefault(require("../minecraft/AttachableResourceDefinition")); const FlipbookTextureCatalogDefinition_1 = __importDefault(require("../minecraft/FlipbookTextureCatalogDefinition")); const Database_1 = __importDefault(require("../minecraft/Database")); const JsonUIResourceDefinition_1 = __importDefault(require("../minecraft/JsonUIResourceDefinition")); const ContentIndex_1 = require("../core/ContentIndex"); const TextureDefinition_1 = __importDefault(require("../minecraft/TextureDefinition")); var TextureInfoGeneratorTest; (function (TextureInfoGeneratorTest) { TextureInfoGeneratorTest[TextureInfoGeneratorTest["tooManyTextureHandles"] = 100] = "tooManyTextureHandles"; TextureInfoGeneratorTest[TextureInfoGeneratorTest["textures"] = 101] = "textures"; })(TextureInfoGeneratorTest || (exports.TextureInfoGeneratorTest = TextureInfoGeneratorTest = {})); /** * Validates texture references and aggregates texture usage information. * * @see {@link ../../public/data/forms/mctoolsval/texture.form.json} for topic definitions */ class TextureInfoGenerator { id = "TEXTURE"; title = "Texture Validation"; performAddOnValidations = false; summarize(info, infoSet) { info.textureCount = infoSet.getSummedDataValue("TEXTURE", TextureInfoGeneratorTest.textures); } /** * Cache for Database.matchesVanillaPath() results across calls. * The same texture paths are checked many times; caching eliminates redundant folder I/O. */ _vanillaPathCache = new Map(); /** * Cached version of Database.matchesVanillaPath() that avoids repeated folder I/O * for the same texture path. */ async _matchesVanillaPathCached(path) { const cached = this._vanillaPathCache.get(path); if (cached !== undefined) { return cached; } const result = await Database_1.default.matchesVanillaPath(path); this._vanillaPathCache.set(path, result); return result; } async generate(project, contentIndex) { const items = []; const textureHandles = new Set(); const allTexturePaths = new Set(); const blockTextureRefs = new Set(); const blockTexturePaths = new Set(); const entityTexturePaths = new Set(); const entityVanillaTexturePaths = new Set(); const attachableTextureRefs = new Set(); const particleTextureRefs = new Set(); const particleTexturePaths = new Set(); const particleVanillaTexturePaths = new Set(); const jsonUITextureRefs = new Set(); const jsonUITexturePaths = new Set(); const jsonUIVanillaTexturePaths = new Set(); const terrainTextureRefs = new Set(); const terrainTexturePaths = new Set(); const flipbookTextureRefs = new Set(); const flipbookTexturePaths = new Set(); const itemTexturePaths = new Set(); const itemTextureVanillaPaths = new Set(); const entitySpawnEggTextures = new Set(); const textureCountPi = new ProjectInfoItem_1.default(IInfoItemData_1.InfoItemType.featureAggregate, this.id, TextureInfoGeneratorTest.textures, "Textures"); items.push(textureCountPi); // Process each item type separately using getItemsByType() for efficiency, // instead of iterating all 15K items and filtering by type. const blocksCatalogItems = project.getItemsByType(IProjectItemData_1.ProjectItemType.blocksCatalogResourceJson); const particleItems = project.getItemsByType(IProjectItemData_1.ProjectItemType.particleJson); const uiItems = project.getItemsByType(IProjectItemData_1.ProjectItemType.uiJson); const terrainTexItems = project.getItemsByType(IProjectItemData_1.ProjectItemType.terrainTextureCatalogResourceJson); const flipbookItems = project.getItemsByType(IProjectItemData_1.ProjectItemType.flipbookTexturesJson); const itemTexItems = project.getItemsByType(IProjectItemData_1.ProjectItemType.itemTextureJson); const entityResItems = project.getItemsByType(IProjectItemData_1.ProjectItemType.entityTypeResource); const attachableItems = project.getItemsByType(IProjectItemData_1.ProjectItemType.attachableResourceJson); const textureItems = project.getItemsByType(IProjectItemData_1.ProjectItemType.texture); const uiTextureItems = project.getItemsByType(IProjectItemData_1.ProjectItemType.uiTexture); for (const projectItem of blocksCatalogItems) { if (!projectItem.isContentLoaded) { await projectItem.loadContent(); } if (!projectItem.primaryFile) { continue; } const blockCat = await BlocksCatalogDefinition_1.default.ensureOnFile(projectItem.primaryFile); if (!blockCat?.blocksCatalog) { continue; } for (const resourceId in blockCat.blocksCatalog) { const resource = blockCat.blocksCatalog[resourceId]; if (!resource?.textures) { continue; } textureCountPi.incrementFeature("Block Resource Count"); blockTextureRefs.add(resourceId); if (typeof resource.textures === "string") { allTexturePaths.add(resource.textures); blockTexturePaths.add(resource.textures); } else { for (const texturePathKey in resource.textures) { const textureVal = resource.textures[texturePathKey]; allTexturePaths.add(textureVal); blockTexturePaths.add(textureVal); } } } } for (const projectItem of particleItems) { if (!projectItem.isContentLoaded) { await projectItem.loadContent(); } if (!projectItem.primaryFile) { continue; } const particleEffect = await ParticleEffectResourceDefinition_1.default.ensureOnFile(projectItem.primaryFile); const desc = particleEffect?.data?.particle_effect?.description; if (!desc?.identifier || !desc.basic_render_parameters?.texture) { continue; } const texturePath = desc.basic_render_parameters.texture; const matchesVP = await this._matchesVanillaPathCached(desc.basic_render_parameters.texture); if (!matchesVP) { textureHandles.add(texturePath); particleTextureRefs.add(desc.identifier); allTexturePaths.add(texturePath); particleTexturePaths.add(texturePath); } else { particleVanillaTexturePaths.add(texturePath); } } for (const projectItem of uiItems) { if (!projectItem.isContentLoaded) { await projectItem.loadContent(); } if (!projectItem.primaryFile) { continue; } const jsonUI = await JsonUIResourceDefinition_1.default.ensureOnFile(projectItem.primaryFile); if (!jsonUI) { continue; } for (const ref of jsonUI.getControlRefs()) { jsonUITextureRefs.add(ref); } const texturePaths = jsonUI.getTexturePaths(); for (const texturePath of texturePaths) { const matchesVP = await this._matchesVanillaPathCached(texturePath); if (!matchesVP) { textureHandles.add(texturePath); allTexturePaths.add(texturePath); jsonUITexturePaths.add(texturePath); } else { jsonUIVanillaTexturePaths.add(texturePath); } } } for (const projectItem of terrainTexItems) { if (!projectItem.isContentLoaded) { await projectItem.loadContent(); } if (!projectItem.primaryFile) { continue; } const terrainTextureCat = await TerrainTextureCatalogDefinition_1.default.ensureOnFile(projectItem.primaryFile); if (!terrainTextureCat?.data?.texture_data) { continue; } for (const terrainTextureId in terrainTextureCat.data.texture_data) { const terrainTexture = terrainTextureCat.data.texture_data[terrainTextureId]; if (!terrainTexture?.textures) { continue; } textureCountPi.incrementFeature("Terrain Texture Resource Count"); terrainTextureRefs.add(terrainTextureId); if (typeof terrainTexture.textures === "string") { terrainTexturePaths.add(terrainTexture.textures); } } } for (const projectItem of flipbookItems) { if (!projectItem.isContentLoaded) { await projectItem.loadContent(); } if (!projectItem.primaryFile) { continue; } const flipbookTexturesCat = await FlipbookTextureCatalogDefinition_1.default.ensureOnFile(projectItem.primaryFile); if (!flipbookTexturesCat?.data || !Array.isArray(flipbookTexturesCat.data)) { continue; } const pathId = projectItem.primaryFile.storageRelativePath + "_flipbooktextures"; allTexturePaths.add(pathId); for (const flipbookTexture of flipbookTexturesCat.data) { if (!flipbookTexture?.flipbook_texture) { continue; } textureCountPi.incrementFeature("Flipbook Texture Resource Count"); textureHandles.add(flipbookTexture.flipbook_texture); flipbookTextureRefs.add(flipbookTexture.atlas_tile); flipbookTexturePaths.add(flipbookTexture.flipbook_texture); } } for (const projectItem of itemTexItems) { if (!projectItem.isContentLoaded) { await projectItem.loadContent(); } if (!projectItem.primaryFile) { continue; } const itemTextureCat = await ItemTextureCatalogDefinition_1.default.ensureOnFile(projectItem.primaryFile); if (!itemTextureCat) { continue; } const texturePaths = itemTextureCat.getTexturePathList(); if (!texturePaths) { continue; } textureCountPi.incrementFeature("Item Texture Resource Count"); for (const str of texturePaths) { const matchesVP = await this._matchesVanillaPathCached(str); if (!matchesVP) { itemTexturePaths.add(str); } else { itemTextureVanillaPaths.add(str); } } } for (const projectItem of entityResItems) { textureCountPi.incrementFeature("Entity Resource Count"); if (!projectItem.isContentLoaded) { await projectItem.loadContent(); } if (!projectItem.primaryFile) { continue; } const entityTypeResourceDef = await EntityTypeResourceDefinition_1.default.ensureOnFile(projectItem.primaryFile); const textures = entityTypeResourceDef?.data?.textures; if (!textures) { continue; } let textureCount = 0; for (const texture in textures) { const texturePath = textures[texture]; if (texturePath) { const matchesVP = await this._matchesVanillaPathCached(texturePath); if (!matchesVP) { textureHandles.add(texturePath); entityTexturePaths.add(texturePath); allTexturePaths.add(texturePath); } else { entityVanillaTexturePaths.add(texturePath); } } textureCount++; } textureCountPi.incrementFeature("Texture References", "Count", textureCount); textureCountPi.incrementFeature("Entity References", "Count", textureCount); } for (const projectItem of attachableItems) { textureCountPi.incrementFeature("Attachable Resource Count"); if (!projectItem.isContentLoaded) { await projectItem.loadContent(); } if (!projectItem.primaryFile) { continue; } const attachableResourceDef = await AttachableResourceDefinition_1.default.ensureOnFile(projectItem.primaryFile); const textures = attachableResourceDef?.data?.textures; if (!textures) { continue; } let textureCount = 0; for (const texture in textures) { const texturePath = textures[texture]; if (texturePath) { textureHandles.add(texturePath); attachableTextureRefs.add(texturePath); allTexturePaths.add(texturePath); textureCount++; } } textureCountPi.incrementFeature("Texture References", "Count", textureCount); textureCountPi.incrementFeature("Attachable References", "Count", textureCount); } // Process texture and UI texture items const allTextureSourceItems = [...textureItems, ...uiTextureItems]; for (const projectItem of allTextureSourceItems) { if (!projectItem.isContentLoaded) { await projectItem.loadContent(); } if (!projectItem.primaryFile) { continue; } textureCountPi.incrementFeature("File Count"); const textureResourceDef = await TextureDefinition_1.default.ensureOnFile(projectItem.primaryFile); if (!textureResourceDef?.data) { continue; } const texturePath = textureResourceDef.getReferencePath(); if (texturePath && projectItem.projectPath) { contentIndex.insert(texturePath, projectItem.projectPath, ContentIndex_1.AnnotationCategory.textureFile); } } if (textureHandles.size > 0) { textureCountPi.incrementFeature("Unique Texture Handles (estimated)", "Count", textureHandles.size); } if (allTexturePaths.size > 0) { textureCountPi.incrementFeature("Unique Texture Paths", "Count", allTexturePaths.size); } if (particleTextureRefs.size > 0) { textureCountPi.incrementFeature("Unique Particle Texture References", "Count", particleTextureRefs.size); } if (particleTexturePaths.size > 0) { textureCountPi.incrementFeature("Unique Particle Texture Paths", "Count", particleTexturePaths.size); } if (particleVanillaTexturePaths.size > 0) { textureCountPi.incrementFeature("Unique Particle Texture Vanilla Paths", "Count", particleVanillaTexturePaths.size); } if (jsonUITextureRefs.size > 0) { textureCountPi.incrementFeature("Unique JSON UI Texture References", "Count", jsonUITextureRefs.size); } if (jsonUITexturePaths.size > 0) { textureCountPi.incrementFeature("Unique JSON UI Texture Paths", "Count", jsonUITexturePaths.size); } if (jsonUIVanillaTexturePaths.size > 0) { textureCountPi.incrementFeature("Unique JSON UI Texture Vanilla Paths", "Count", jsonUIVanillaTexturePaths.size); } if (entityTexturePaths.size > 0) { textureCountPi.incrementFeature("Unique Entity Texture Paths", "Count", entityTexturePaths.size); } if (entityVanillaTexturePaths.size > 0) { textureCountPi.incrementFeature("Unique Entity Texture Vanilla Paths", "Count", entityVanillaTexturePaths.size); } if (attachableTextureRefs.size > 0) { textureCountPi.incrementFeature("Unique Attachable Texture References", "Count", attachableTextureRefs.size); } if (terrainTextureRefs.size > 0) { textureCountPi.incrementFeature("Unique Terrain Texture References", "Count", terrainTextureRefs.size); } if (terrainTexturePaths.size > 0) { textureCountPi.incrementFeature("Unique Terrain Texture Paths", "Count", terrainTexturePaths.size); } if (itemTexturePaths.size > 0) { textureCountPi.incrementFeature("Unique Item Texture Paths", "Count", itemTexturePaths.size); } if (flipbookTextureRefs.size > 0) { textureCountPi.incrementFeature("Unique Flipbook Texture References", "Count", flipbookTextureRefs.size); } if (flipbookTexturePaths.size > 0) { textureCountPi.incrementFeature("Unique Flipbook Texture Paths", "Count", flipbookTexturePaths.size); } if (blockTextureRefs.size > 0) { textureCountPi.incrementFeature("Unique Block Texture References", "Count", blockTextureRefs.size); } if (blockTexturePaths.size > 0) { textureCountPi.incrementFeature("Unique Block Texture Paths", "Count", blockTexturePaths.size); } if (entitySpawnEggTextures.size > 0) { textureCountPi.incrementFeature("Unique Entity Spawn Egg Texture References", "Count", entitySpawnEggTextures.size); } if (this.performAddOnValidations && textureHandles.size > 800) { items.push(new ProjectInfoItem_1.default(IInfoItemData_1.InfoItemType.error, this.id, TextureInfoGeneratorTest.tooManyTextureHandles, "Uses more than 800 texture handles, which could impact overall Minecraft usage", undefined, textureHandles.size)); } return items; } } exports.default = TextureInfoGenerator;