UNPKG

@minecraft/creator-tools

Version:

Minecraft Creator Tools command line and libraries.

436 lines (435 loc) 30.4 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.WorldDataInfoGeneratorTest = exports.MaxWorldRecordsToProcess = void 0; const ProjectInfoItem_1 = __importDefault(require("./ProjectInfoItem")); const IProjectItemData_1 = require("../app/IProjectItemData"); const MCWorld_1 = __importDefault(require("../minecraft/MCWorld")); const Log_1 = __importDefault(require("../core/Log")); const IInfoItemData_1 = require("./IInfoItemData"); const CommandBlockActor_1 = __importDefault(require("../minecraft/blockActors/CommandBlockActor")); const Status_1 = require("../app/Status"); const CommandStructure_1 = __importDefault(require("../app/CommandStructure")); const CommandRegistry_1 = __importDefault(require("../app/CommandRegistry")); const Dialogue_1 = __importDefault(require("../minecraft/Dialogue")); const ContentIndex_1 = require("../core/ContentIndex"); const NbtBinaryTag_1 = require("../minecraft/NbtBinaryTag"); const AnimationControllerBehaviorDefinition_1 = __importDefault(require("../minecraft/AnimationControllerBehaviorDefinition")); const AnimationBehaviorDefinition_1 = __importDefault(require("../minecraft/AnimationBehaviorDefinition")); const ProjectInfoUtilities_1 = __importDefault(require("./ProjectInfoUtilities")); const WorldLevelDat_1 = require("../minecraft/WorldLevelDat"); const ProjectInfoSet_1 = require("./ProjectInfoSet"); exports.MaxWorldRecordsToProcess = 3000000; // very crudely, this equates to about 100K chunks /** * Validates and aggregates world data including command blocks and level.dat information. * * @see {@link ../../public/data/forms/mctoolsval/worlddata.form.json} for topic definitions */ var WorldDataInfoGeneratorTest; (function (WorldDataInfoGeneratorTest) { WorldDataInfoGeneratorTest[WorldDataInfoGeneratorTest["unexpectedCommandInMCFunction"] = 101] = "unexpectedCommandInMCFunction"; WorldDataInfoGeneratorTest[WorldDataInfoGeneratorTest["unexpectedCommandInCommandBlock"] = 102] = "unexpectedCommandInCommandBlock"; WorldDataInfoGeneratorTest[WorldDataInfoGeneratorTest["minX"] = 103] = "minX"; WorldDataInfoGeneratorTest[WorldDataInfoGeneratorTest["minZ"] = 104] = "minZ"; WorldDataInfoGeneratorTest[WorldDataInfoGeneratorTest["maxX"] = 105] = "maxX"; WorldDataInfoGeneratorTest[WorldDataInfoGeneratorTest["maxZ"] = 106] = "maxZ"; WorldDataInfoGeneratorTest[WorldDataInfoGeneratorTest["containsWorldImpactingCommand"] = 112] = "containsWorldImpactingCommand"; WorldDataInfoGeneratorTest[WorldDataInfoGeneratorTest["blocks"] = 121] = "blocks"; WorldDataInfoGeneratorTest[WorldDataInfoGeneratorTest["blockData"] = 122] = "blockData"; WorldDataInfoGeneratorTest[WorldDataInfoGeneratorTest["command"] = 123] = "command"; WorldDataInfoGeneratorTest[WorldDataInfoGeneratorTest["executeSubCommand"] = 124] = "executeSubCommand"; WorldDataInfoGeneratorTest[WorldDataInfoGeneratorTest["levelDat"] = 125] = "levelDat"; WorldDataInfoGeneratorTest[WorldDataInfoGeneratorTest["levelDatExperiments"] = 126] = "levelDatExperiments"; WorldDataInfoGeneratorTest[WorldDataInfoGeneratorTest["subchunklessChunks"] = 127] = "subchunklessChunks"; WorldDataInfoGeneratorTest[WorldDataInfoGeneratorTest["chunks"] = 128] = "chunks"; WorldDataInfoGeneratorTest[WorldDataInfoGeneratorTest["commandIsFromOlderMinecraftVersion"] = 212] = "commandIsFromOlderMinecraftVersion"; WorldDataInfoGeneratorTest[WorldDataInfoGeneratorTest["couldNotProcessWorld"] = 216] = "couldNotProcessWorld"; WorldDataInfoGeneratorTest[WorldDataInfoGeneratorTest["errorProcessingWorld"] = 400] = "errorProcessingWorld"; WorldDataInfoGeneratorTest[WorldDataInfoGeneratorTest["unexpectedError"] = 401] = "unexpectedError"; })(WorldDataInfoGeneratorTest || (exports.WorldDataInfoGeneratorTest = WorldDataInfoGeneratorTest = {})); class WorldDataInfoGenerator { id = "WORLDDATA"; title = "World Data Validation"; modernCommandVersion = 33; // corresponds to 1.20.0 versions of Minecraft. performAddOnValidations = false; performPlatformVersionValidations = false; summarize(info, infoSet) { info.chunkCount = infoSet.getSummedDataValue("WORLDDATA", WorldDataInfoGeneratorTest.chunks); info.subchunkLessChunkCount = infoSet.getSummedDataValue("WORLDDATA", WorldDataInfoGeneratorTest.subchunklessChunks); info.completedWorldDataProcessing = infoSet.getCount("WORLDDATA", WorldDataInfoGeneratorTest.couldNotProcessWorld) === 0; info.worldLoadErrors = infoSet.getCount("WORLDDATA", WorldDataInfoGeneratorTest.errorProcessingWorld); const levelItems = infoSet.getItems(this.id, WorldDataInfoGeneratorTest.levelDat); const capabilitiesSet = new Set(info.capabilities); for (const levelItem of levelItems) { if (levelItem && levelItem.featureSets) { const gameType = levelItem.featureSets.GameType; if (gameType !== undefined) { if (gameType[WorldLevelDat_1.GameType.adventure] !== undefined && gameType[WorldLevelDat_1.GameType.adventure] > 0) { if (!capabilitiesSet.has("adventure")) { info.capabilities.push("adventure"); capabilitiesSet.add("adventure"); } } if (gameType[WorldLevelDat_1.GameType.survival] !== undefined && gameType[WorldLevelDat_1.GameType.survival] > 0) { if (!capabilitiesSet.has("survival")) { info.capabilities.push("survival"); capabilitiesSet.add("survival"); } } if (gameType[WorldLevelDat_1.GameType.creative] !== undefined && gameType[WorldLevelDat_1.GameType.creative] > 0) { if (!capabilitiesSet.has("creative")) { info.capabilities.push("creative"); capabilitiesSet.add("creative"); } } } } } info.commands = []; const commandsSet = new Set(); const commandItems = infoSet.getItems(this.id, WorldDataInfoGeneratorTest.command); const subCommandItems = infoSet.getItems(this.id, WorldDataInfoGeneratorTest.executeSubCommand); for (const commandItem of commandItems) { let commandNames = commandItem.featureSets; if (commandNames) { for (const commandName in commandNames) { if (!commandsSet.has(commandName)) { info.commands.push(commandName); commandsSet.add(commandName); } } } } for (const commandItem of subCommandItems) { let commandNames = commandItem.featureSets; if (commandNames) { for (const commandName in commandNames) { if (!commandsSet.has(commandName)) { info.commands.push(commandName); commandsSet.add(commandName); } } } } info.commands.sort(); } processListOfCommands(commandList, items, projectItem, commandsPi, subCommandsPi, checkForSlash) { for (let i = 0; i < commandList.length; i++) { if (commandList[i].trim().length > 0 && (!checkForSlash || commandList[i].startsWith("/"))) { const command = CommandStructure_1.default.parse(commandList[i]); if (command.fullName.length === 0) { continue; } if (CommandRegistry_1.default.isMinecraftBuiltInCommand(command.fullName)) { if (this.performAddOnValidations && CommandRegistry_1.default.isAddOnBlockedCommand(command.fullName)) { items.push(new ProjectInfoItem_1.default(IInfoItemData_1.InfoItemType.warning, this.id, WorldDataInfoGeneratorTest.containsWorldImpactingCommand, "Contains command '" + command.fullName + "' which is impacts the state of the entire world, and generally shouldn't be used in an add-on", projectItem, command.fullName, undefined, commandList[i])); } commandsPi.incrementFeature(command.fullName); if (command.fullName === "execute") { let foundRun = false; for (const arg of command.commandArguments) { if (arg === "run") { foundRun = true; } else if (foundRun && CommandRegistry_1.default.isMinecraftBuiltInCommand(arg)) { subCommandsPi.incrementFeature(arg); break; } } } } else if (!this.performPlatformVersionValidations && !this.performAddOnValidations) { items.push(new ProjectInfoItem_1.default(IInfoItemData_1.InfoItemType.error, this.id, WorldDataInfoGeneratorTest.unexpectedCommandInCommandBlock, "Unexpected command '" + command.fullName + "'", projectItem, command.fullName, undefined, commandList[i])); } } } } async generate(projectItem, contentIndex, options) { const items = []; const performAggressiveCleanup = options?.performAggressiveCleanup ?? false; const onProgress = options?.onProgress; if (projectItem.itemType !== IProjectItemData_1.ProjectItemType.MCWorld && projectItem.itemType !== IProjectItemData_1.ProjectItemType.MCTemplate && projectItem.itemType !== IProjectItemData_1.ProjectItemType.worldFolder && projectItem.itemType !== IProjectItemData_1.ProjectItemType.dialogueBehaviorJson && projectItem.itemType !== IProjectItemData_1.ProjectItemType.animationControllerBehaviorJson && projectItem.itemType !== IProjectItemData_1.ProjectItemType.animationBehaviorJson && projectItem.itemType !== IProjectItemData_1.ProjectItemType.MCFunction) { return items; } // Determine if this is a world-type item (needs all aggregates) or just command-related const isWorldType = projectItem.itemType === IProjectItemData_1.ProjectItemType.MCWorld || projectItem.itemType === IProjectItemData_1.ProjectItemType.MCTemplate || projectItem.itemType === IProjectItemData_1.ProjectItemType.worldFolder; // World-specific aggregates - only create for world items let blocksPi; let blockActorsPi; let nbtPi; let nbtExperimentsPi; if (isWorldType) { blocksPi = new ProjectInfoItem_1.default(IInfoItemData_1.InfoItemType.featureAggregate, this.id, WorldDataInfoGeneratorTest.blocks, ProjectInfoUtilities_1.default.getTitleFromEnum(WorldDataInfoGeneratorTest, WorldDataInfoGeneratorTest.blocks), projectItem); items.push(blocksPi); blockActorsPi = new ProjectInfoItem_1.default(IInfoItemData_1.InfoItemType.featureAggregate, this.id, WorldDataInfoGeneratorTest.blockData, ProjectInfoUtilities_1.default.getTitleFromEnum(WorldDataInfoGeneratorTest, WorldDataInfoGeneratorTest.blockData), projectItem); items.push(blockActorsPi); nbtPi = new ProjectInfoItem_1.default(IInfoItemData_1.InfoItemType.featureAggregate, this.id, WorldDataInfoGeneratorTest.levelDat, ProjectInfoUtilities_1.default.getTitleFromEnum(WorldDataInfoGeneratorTest, WorldDataInfoGeneratorTest.levelDat), projectItem); items.push(nbtPi); nbtExperimentsPi = new ProjectInfoItem_1.default(IInfoItemData_1.InfoItemType.featureAggregate, this.id, WorldDataInfoGeneratorTest.levelDatExperiments, ProjectInfoUtilities_1.default.getTitleFromEnum(WorldDataInfoGeneratorTest, WorldDataInfoGeneratorTest.levelDatExperiments), projectItem); items.push(nbtExperimentsPi); } // Command aggregates - used by all supported item types const commandsPi = new ProjectInfoItem_1.default(IInfoItemData_1.InfoItemType.featureAggregate, this.id, WorldDataInfoGeneratorTest.command, ProjectInfoUtilities_1.default.getTitleFromEnum(WorldDataInfoGeneratorTest, WorldDataInfoGeneratorTest.command), projectItem); items.push(commandsPi); const subCommandsPi = new ProjectInfoItem_1.default(IInfoItemData_1.InfoItemType.featureAggregate, this.id, WorldDataInfoGeneratorTest.executeSubCommand, ProjectInfoUtilities_1.default.getTitleFromEnum(WorldDataInfoGeneratorTest, WorldDataInfoGeneratorTest.executeSubCommand), projectItem); items.push(subCommandsPi); if (projectItem.itemType === IProjectItemData_1.ProjectItemType.dialogueBehaviorJson) { if (!projectItem.isContentLoaded) { await projectItem.loadContent(); } if (projectItem.primaryFile) { const diaManifest = await Dialogue_1.default.ensureOnFile(projectItem.primaryFile); if (diaManifest && diaManifest.definition && diaManifest.definition["minecraft:npc_dialogue"]) { let scenes = diaManifest.definition["minecraft:npc_dialogue"].scenes; for (const scene of scenes) { if (scene.on_open_commands) { this.processListOfCommands(scene.on_open_commands, items, projectItem, commandsPi, subCommandsPi, true); } if (scene.on_close_commands) { this.processListOfCommands(scene.on_close_commands, items, projectItem, commandsPi, subCommandsPi, true); } } let buttons = diaManifest.getAllButtons(); for (const button of buttons) { if (button.commands) { this.processListOfCommands(button.commands, items, projectItem, commandsPi, subCommandsPi, true); } } } } } else if (projectItem.itemType === IProjectItemData_1.ProjectItemType.animationControllerBehaviorJson) { if (!projectItem.isContentLoaded) { await projectItem.loadContent(); } if (projectItem.primaryFile) { const acManifest = await AnimationControllerBehaviorDefinition_1.default.ensureOnFile(projectItem.primaryFile); if (acManifest && acManifest.data && acManifest.data.animation_controllers) { let states = acManifest.getAllStates(); for (const state of states) { if (state.state.on_entry) { this.processListOfCommands(state.state.on_entry, items, projectItem, commandsPi, subCommandsPi, true); } if (state.state.on_exit) { this.processListOfCommands(state.state.on_exit, items, projectItem, commandsPi, subCommandsPi, true); } } } } } else if (projectItem.itemType === IProjectItemData_1.ProjectItemType.animationBehaviorJson) { if (!projectItem.isContentLoaded) { await projectItem.loadContent(); } if (projectItem.primaryFile) { const animManifest = await AnimationBehaviorDefinition_1.default.ensureOnFile(projectItem.primaryFile); if (animManifest && animManifest.data && animManifest.data.animations) { let timelines = animManifest.getAllTimeline(); for (const timeline of timelines) { if (timeline.timeline) { this.processListOfCommands(timeline.timeline, items, projectItem, commandsPi, subCommandsPi, true); } } } } } else if (projectItem.itemType === IProjectItemData_1.ProjectItemType.MCFunction) { let content = await projectItem.getStringContent(); if (content !== undefined) { let contentLines = content.split("\n"); this.processListOfCommands(contentLines, items, projectItem, commandsPi, subCommandsPi, false); } } if (projectItem.itemType === IProjectItemData_1.ProjectItemType.MCWorld || projectItem.itemType === IProjectItemData_1.ProjectItemType.MCTemplate || projectItem.itemType === IProjectItemData_1.ProjectItemType.worldFolder) { let mcworld = await MCWorld_1.default.ensureOnItem(projectItem); if (!mcworld) { Log_1.default.debugAlert("Could not find respective world."); return items; } await mcworld.loadMetaFiles(false); // Determine whether to apply record processing limits based on resource consumption constraint const constrainResources = options?.constrainResourceConsumption !== ProjectInfoSet_1.ResourceConsumptionConstraint.none; const maxRecordsToProcess = constrainResources ? exports.MaxWorldRecordsToProcess : undefined; let didProcessWorldData = await mcworld.loadLevelDb(false, { maxNumberOfRecordsToProcess: maxRecordsToProcess, }); if (mcworld.isInErrorState && mcworld.errorMessages && !this.performAddOnValidations && !this.performPlatformVersionValidations) { for (const err of mcworld.errorMessages) { items.push(new ProjectInfoItem_1.default(IInfoItemData_1.InfoItemType.error, this.id, WorldDataInfoGeneratorTest.errorProcessingWorld, ProjectInfoUtilities_1.default.getTitleFromEnum(WorldDataInfoGeneratorTest, WorldDataInfoGeneratorTest.errorProcessingWorld), projectItem, err.message + (err.context ? " - " + err.context : ""), mcworld.name)); } didProcessWorldData = false; } if (!didProcessWorldData) { items.push(new ProjectInfoItem_1.default(IInfoItemData_1.InfoItemType.info, this.id, WorldDataInfoGeneratorTest.couldNotProcessWorld, ProjectInfoUtilities_1.default.getTitleFromEnum(WorldDataInfoGeneratorTest, WorldDataInfoGeneratorTest.couldNotProcessWorld), projectItem, mcworld.name)); } if (projectItem.projectPath && contentIndex && mcworld.levelData && mcworld.levelData.nbt && mcworld.levelData.nbt.singleRoot) { const children = mcworld.levelData.nbt.singleRoot.getTagChildren(); for (const child of children) { if (child.name === "experiments") { for (const experimentChild of child.getTagChildren()) { if (experimentChild.type === NbtBinaryTag_1.NbtTagType.int || experimentChild.type === NbtBinaryTag_1.NbtTagType.byte || experimentChild.type === NbtBinaryTag_1.NbtTagType.string) { nbtExperimentsPi?.incrementFeature(experimentChild.name, experimentChild.valueAsString); contentIndex.insert(experimentChild.name + "==" + experimentChild.valueAsString, projectItem.projectPath, ContentIndex_1.AnnotationCategory.experiment); } } } else if (child.type === NbtBinaryTag_1.NbtTagType.int || child.type === NbtBinaryTag_1.NbtTagType.byte || child.type === NbtBinaryTag_1.NbtTagType.string) { if (child.name !== "LevelName" && child.name !== "FlatWorldLayers" && child.name !== "lightningTime" && child.name !== "EducationOid" && child.name !== "EducationProductId" && child.name !== "rainTime" && child.name !== "worldTemplateUUID" && !child.name.startsWith("LimitedWorld") && !child.name.startsWith("SpawnX") && !child.name.startsWith("SpawnY") && !child.name.startsWith("SpawnZ")) { if (child.name.indexOf("ersion") >= 0 && !child.valueAsString.startsWith("1.")) { nbtPi?.incrementFeature(child.name, "(unknown version)"); } else { nbtPi?.incrementFeature(child.name, child.valueAsString); } contentIndex.insert(child.name + "==" + child.valueAsString, projectItem.projectPath, ContentIndex_1.AnnotationCategory.worldProperty); } } } } items.push(new ProjectInfoItem_1.default(IInfoItemData_1.InfoItemType.info, this.id, WorldDataInfoGeneratorTest.chunks, ProjectInfoUtilities_1.default.getTitleFromEnum(WorldDataInfoGeneratorTest, WorldDataInfoGeneratorTest.chunks), projectItem, mcworld.chunkCount, mcworld.name)); if (didProcessWorldData) { let blockCount = 0; let chunkCount = 0; let subchunkLessChunkCount = 0; // Use the memory-efficient chunk iterator with aggressive data clearing // This prevents heap exhaustion on large worlds by clearing chunk data after processing await mcworld.forEachChunk(async (chunk, x, z, dimIndex) => { chunkCount++; if (chunk.subChunks.length <= 0) { subchunkLessChunkCount++; } const blockActors = chunk.blockActors; for (let i = 0; i < blockActors.length; i++) { const blockActor = blockActors[i]; if (blockActor.id) { blockActorsPi?.incrementFeature(blockActor.id); } if (blockActor instanceof CommandBlockActor_1.default) { let cba = blockActor; if (cba.version) { blockActorsPi?.spectrumIntFeature("Command Version", cba.version); } if (cba.version && cba.version < this.modernCommandVersion) { items.push(new ProjectInfoItem_1.default(IInfoItemData_1.InfoItemType.recommendation, this.id, WorldDataInfoGeneratorTest.commandIsFromOlderMinecraftVersion, "Command '" + cba.command + "' is from an older Minecraft version (" + cba.version + ") ", projectItem, "(Command at location " + cba.x + ", " + cba.y + ", " + cba.z + ")", undefined, cba.command)); } if (cba.command && cba.command.trim().length > 0) { let command = CommandStructure_1.default.parse(cba.command); if (command.fullName.length === 0) { // Skip empty command names (e.g., command block containing just "/") } else if (CommandRegistry_1.default.isMinecraftBuiltInCommand(command.fullName)) { if (this.performAddOnValidations && CommandRegistry_1.default.isAddOnBlockedCommand(command.fullName)) { items.push(new ProjectInfoItem_1.default(IInfoItemData_1.InfoItemType.warning, this.id, WorldDataInfoGeneratorTest.containsWorldImpactingCommand, "Contains command '" + command.fullName + "' which is impacts the state of the entire world, and generally shouldn't be used in an add-on", projectItem, command.fullName, undefined, cba.command)); } commandsPi.incrementFeature(command.fullName); if (command.fullName === "execute") { let foundRun = false; for (const arg of command.commandArguments) { if (arg === "run") { foundRun = true; } else if (foundRun && CommandRegistry_1.default.isMinecraftBuiltInCommand(arg)) { subCommandsPi.incrementFeature(arg); break; } } } } else if (!this.performAddOnValidations && !this.performPlatformVersionValidations) { items.push(new ProjectInfoItem_1.default(IInfoItemData_1.InfoItemType.error, this.id, WorldDataInfoGeneratorTest.unexpectedCommandInCommandBlock, "Unexpected command '" + command.fullName + "'", projectItem, command.fullName, undefined, cba.command)); } } } } // Use memory-efficient block type counting instead of getBlockList() // This avoids allocating massive arrays of Block objects const blockTypeCounts = chunk.countBlockTypes(); for (const [typeName, count] of blockTypeCounts) { blockCount += count; let type = typeName; if (type.indexOf(":") >= 0 && type.indexOf("minecraft:") < 0) { type = "(custom)"; } blocksPi?.incrementFeature(type, "count", count); } }, { // Always clear parsed/cached data after processing each chunk to prevent OOM. // This is non-destructive - raw LevelKeyValue bytes are preserved, so chunks // can be re-parsed on demand (e.g., when the world map needs them). clearCacheAfterProcess: true, // Only clear raw LevelKeyValue data when in aggressive cleanup mode (CLI validation). // In browser contexts, we preserve raw data so the world map can re-parse chunks. clearAllAfterProcess: performAggressiveCleanup, progressCallback: async (processed, total) => { // Use worldName captured from outside closure to avoid TypeScript null check issue const worldName = mcworld?.name ?? "unknown"; const chunkPercent = total > 0 ? Math.floor((processed / total) * 100) : 0; let mess = "World validation: scanned " + Math.floor(processed / 1000) + "K of " + Math.floor(total / 1000) + "K chunks in " + worldName; // Report granular progress via onProgress callback if available // Map chunk progress (0-100%) to the 30-80% range of overall validation if (onProgress) { const overallPercent = Math.floor(30 + chunkPercent * 0.5); // 30-80% onProgress(mess, overallPercent); } await projectItem.project.creatorTools.notifyStatusUpdate(mess, Status_1.StatusTopic.validation); }, }); items.push(new ProjectInfoItem_1.default(IInfoItemData_1.InfoItemType.info, this.id, WorldDataInfoGeneratorTest.subchunklessChunks, "Subchunkless Chunks", projectItem, subchunkLessChunkCount, mcworld.name)); if (blocksPi) { blocksPi.data = blockCount; } } items.push(new ProjectInfoItem_1.default(IInfoItemData_1.InfoItemType.info, this.id, WorldDataInfoGeneratorTest.minX, ProjectInfoUtilities_1.default.getTitleFromEnum(WorldDataInfoGeneratorTest, WorldDataInfoGeneratorTest.minX), projectItem, mcworld.minX, mcworld.name)); items.push(new ProjectInfoItem_1.default(IInfoItemData_1.InfoItemType.info, this.id, WorldDataInfoGeneratorTest.minZ, ProjectInfoUtilities_1.default.getTitleFromEnum(WorldDataInfoGeneratorTest, WorldDataInfoGeneratorTest.minZ), projectItem, mcworld.minZ, mcworld.name)); items.push(new ProjectInfoItem_1.default(IInfoItemData_1.InfoItemType.info, this.id, WorldDataInfoGeneratorTest.maxX, ProjectInfoUtilities_1.default.getTitleFromEnum(WorldDataInfoGeneratorTest, WorldDataInfoGeneratorTest.maxX), projectItem, mcworld.maxX, mcworld.name)); items.push(new ProjectInfoItem_1.default(IInfoItemData_1.InfoItemType.info, this.id, WorldDataInfoGeneratorTest.maxZ, ProjectInfoUtilities_1.default.getTitleFromEnum(WorldDataInfoGeneratorTest, WorldDataInfoGeneratorTest.maxZ), projectItem, mcworld.maxZ, mcworld.name)); } return items; } } exports.default = WorldDataInfoGenerator;