UNPKG

@minecraft/creator-tools

Version:

Minecraft Creator Tools command line and libraries.

643 lines (641 loc) 25.7 kB
"use strict"; // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) { if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); }; var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { if (kind === "m") throw new TypeError("Private method is not writable"); if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; }; var _ContentIndex_data, _ContentIndex_iteration; Object.defineProperty(exports, "__esModule", { value: true }); exports.AnnotationCategory = void 0; const Log_1 = require("./Log"); const Utilities_1 = require("./Utilities"); const esprima_next_1 = require("esprima-next"); var AnnotationCategory; (function (AnnotationCategory) { AnnotationCategory["blockTextureReferenceSource"] = "a"; AnnotationCategory["blockTypeDependent"] = "b"; AnnotationCategory["entityComponentDependent"] = "c"; AnnotationCategory["blockComponentDependent"] = "d"; AnnotationCategory["entityTypeDependent"] = "e"; AnnotationCategory["entityFilter"] = "f"; AnnotationCategory["entityComponentDependentInGroup"] = "g"; AnnotationCategory["blockTextureReferenceDependent"] = "h"; AnnotationCategory["itemTypeDependent"] = "i"; AnnotationCategory["itemComponentDependent"] = "j"; AnnotationCategory["itemTextureReferenceSource"] = "k"; AnnotationCategory["featureSource"] = "l"; AnnotationCategory["featureDependent"] = "m"; AnnotationCategory["featureRuleSource"] = "n"; AnnotationCategory["blockComponentDependentInPermutation"] = "p"; AnnotationCategory["storagePathDependent"] = "s"; AnnotationCategory["textureFile"] = "t"; AnnotationCategory["entityEvent"] = "v"; AnnotationCategory["blockTypeSource"] = "B"; AnnotationCategory["entityTypeSource"] = "E"; AnnotationCategory["itemTypeSource"] = "I"; AnnotationCategory["itemTextureSource"] = "J"; AnnotationCategory["blockSounds"] = "L"; AnnotationCategory["musicDefinitionSource"] = "M"; AnnotationCategory["entitySounds"] = "N"; AnnotationCategory["interactiveSounds"] = "R"; AnnotationCategory["jsSource"] = "S"; AnnotationCategory["terrainTextureSource"] = "T"; AnnotationCategory["soundDefinitionSource"] = "U"; AnnotationCategory["individualEventSoundsSource"] = "V"; AnnotationCategory["worldProperty"] = "W"; AnnotationCategory["experiment"] = "X"; })(AnnotationCategory = exports.AnnotationCategory || (exports.AnnotationCategory = {})); const AvoidTermList = ["__proto__", "prototype", "[[Prototype]]"]; class ContentIndex { constructor() { _ContentIndex_data.set(this, { items: [], trie: {}, }); _ContentIndex_iteration.set(this, Math.floor(Math.random() * 1000000)); } get iteration() { return __classPrivateFieldGet(this, _ContentIndex_iteration, "f"); } set iteration(newIteration) { __classPrivateFieldSet(this, _ContentIndex_iteration, newIteration, "f"); } static getAnnotationCategoryKeys() { const keys = []; for (const key in AnnotationCategory) { keys.push(key.toLowerCase()); } return keys; } static getAnnotationCategoryFromLongString(longStr) { longStr = longStr.toLowerCase(); for (const key in AnnotationCategory) { if (key.toLowerCase() === longStr) { return AnnotationCategory[key]; } } return undefined; } get data() { return __classPrivateFieldGet(this, _ContentIndex_data, "f"); } get startLength() { return 4; } setItems(items) { __classPrivateFieldGet(this, _ContentIndex_data, "f").items = items; } setTrie(trie) { __classPrivateFieldGet(this, _ContentIndex_data, "f").trie = trie; } getAll(withAnnotation) { const results = {}; this._appendToResults("", __classPrivateFieldGet(this, _ContentIndex_data, "f").trie, results, withAnnotation); return results; } _isTermToAvoid(term) { return AvoidTermList.includes(term); } _appendToResults(prefix, node, results, withAnnotation) { for (const token in node) { const subNode = node[token]; if (subNode) { if (token === "±" || token === "$") { const arr = subNode; if (arr.constructor === Array) { if (!this._isTermToAvoid(prefix)) { let res = this.getValuesFromIndexArray(arr, withAnnotation); if (res) { results[prefix] = res; } } } } else if (subNode.constructor === Array) { if (!this._isTermToAvoid(prefix + token)) { let res = this.getValuesFromIndexArray(subNode, withAnnotation); if (res) { results[prefix + token] = res; } } } else { this._appendToResults(prefix + token, subNode, results, withAnnotation); } } } } mergeFrom(index, newItem) { const all = index.getAll(); for (const fullKey in all) { const annVals = all[fullKey]; let annVal; for (const subVal of annVals) { if (subVal.annotation) { if (!annVal) { annVal = subVal.annotation; } else if (annVal.indexOf(subVal.annotation) < 0) { annVal += subVal.annotation; } } } this.insert(fullKey, newItem, annVal); } } static processResultValues(annotatedValues, withAnyAnnotation) { if (!annotatedValues) { return undefined; } if (withAnyAnnotation) { let newAnnotatedValues = []; for (const annV of annotatedValues) { if (annV.annotation && withAnyAnnotation.includes(annV.annotation)) { newAnnotatedValues.push(annV); } } annotatedValues = newAnnotatedValues; } return annotatedValues; } getValuesFromIndexArray(indices, withAnnotation) { let results = []; if (!indices) { return undefined; } if (Utilities_1.default.arrayHasNegativeAndIsNumeric(indices)) { indices = Utilities_1.default.decodeSequentialRunLengthUsingNegative(indices); } for (const index of indices) { if (typeof index === "object") { const indexN = index.n; if (indexN >= 0 && indexN < __classPrivateFieldGet(this, _ContentIndex_data, "f").items.length) { const annotate = index.a; if (!withAnnotation || withAnnotation.includes(annotate)) { results.push({ value: __classPrivateFieldGet(this, _ContentIndex_data, "f").items[indexN], annotation: index.a }); } } } else if (index >= 0 && index < __classPrivateFieldGet(this, _ContentIndex_data, "f").items.length && !withAnnotation) { results.push({ value: __classPrivateFieldGet(this, _ContentIndex_data, "f").items[index], annotation: undefined }); } } if (results.length === 0) { return undefined; } return results; } loadFromData(data) { __classPrivateFieldSet(this, _ContentIndex_data, data, "f"); } hasPathMatches(pathEnd) { pathEnd = pathEnd.toLowerCase(); const lastPeriodEnd = pathEnd.lastIndexOf("."); if (lastPeriodEnd >= 0) { pathEnd = pathEnd.substring(0, lastPeriodEnd); } for (let path of this.data.items) { if (path.startsWith("/")) { const lastPeriod = path.lastIndexOf("."); if (lastPeriod >= 0) { path = path.substring(0, lastPeriod); } if (path.endsWith(pathEnd)) { return true; } } } return false; } async getMatches(searchString, wholeTermSearch, withAnyAnnotation) { searchString = searchString.trim().toLowerCase(); let terms = [searchString]; if (!wholeTermSearch) { terms = searchString.split(" "); } let termWasSearched = false; let andResults; for (const term of terms) { if (term.length > 1) { const results = this.getTermMatch(term); termWasSearched = true; if (results && results.length) { if (andResults === undefined) { andResults = results; } else { const newArr = []; for (let num of results) { if (andResults.includes(num)) { newArr.push(num); } } } } } } if (andResults === undefined || andResults.length === 0) { if (termWasSearched) { return []; } return undefined; } let annotatedValues = ContentIndex.processResultValues(this.getValuesFromIndexArray(andResults), withAnyAnnotation); if (!annotatedValues) { return undefined; } return annotatedValues.sort((a, b) => { let aTermMatches = 0; let bTermMatches = 0; const aVal = a.value.toLowerCase(); const bVal = b.value.toLowerCase(); for (const term of terms) { if (aVal.startsWith(term)) { aTermMatches += 5; } else if (aVal.includes(term)) { aTermMatches++; } if (bVal.startsWith(term)) { bTermMatches += 5; } else if (bVal.includes(term)) { bTermMatches++; } } if (aTermMatches === bTermMatches) { return a.value.localeCompare(b.value); } return bTermMatches - aTermMatches; }); } getTermMatchStrings(term) { const results = this.getTermMatch(term); if (results === undefined) { return results; } return this.getValuesFromIndexArray(results); } async getDescendentStrings(term) { let termIndex = 0; let curNode = __classPrivateFieldGet(this, _ContentIndex_data, "f").trie; const results = {}; let hasAdvanced = true; let termSubstr = ""; while (termIndex < term.length && hasAdvanced) { hasAdvanced = false; if (curNode.constructor === Array) { return undefined; } let nextNode = curNode[term[termIndex]]; if (nextNode) { curNode = nextNode; termIndex++; termSubstr = term.substring(0, termIndex); hasAdvanced = true; } else { let nextStart = term[termIndex]; for (const item in curNode) { // we've found part of our string in this node if (item.startsWith(nextStart) && curNode[item] !== undefined) { let itemIndex = 0; hasAdvanced = true; curNode = curNode[item]; termSubstr = term.substring(0, termIndex) + item; while (termIndex < term.length && itemIndex < item.length && item[itemIndex] === term[termIndex]) { itemIndex++; termIndex++; } break; } } } } if (termIndex < term.length) { const termStub = term.substring(termIndex); for (const childNodeName in curNode) { if (childNodeName.startsWith(termStub) && curNode[childNodeName]) { this._appendToResults(term.substring(0, termIndex) + childNodeName, curNode[childNodeName], results); } } } else { if (curNode.constructor === Array) { results[termSubstr] = this.getValuesFromIndexArray(curNode); } else if (curNode["±"] !== undefined) { this._appendToResults(termSubstr, curNode, results); } } return results; } getTermMatch(term) { let termIndex = 0; let curNode = __classPrivateFieldGet(this, _ContentIndex_data, "f").trie; let hasAdvanced = true; while (termIndex < term.length && hasAdvanced) { hasAdvanced = false; if (curNode.constructor === Array) { return undefined; } let nextNode = curNode[term[termIndex]]; if (nextNode) { curNode = nextNode; termIndex++; hasAdvanced = true; } else { let nextStart = term[termIndex]; if (termIndex < term.length - 1) { nextStart += term[termIndex + 1]; } for (const item in curNode) { // we've found part of our string in this node if (item.startsWith(nextStart) && curNode[item] !== undefined && !hasAdvanced) { let itemIndex = 0; hasAdvanced = true; curNode = curNode[item]; while (termIndex < term.length && itemIndex < item.length && item[itemIndex] === term[termIndex]) { itemIndex++; termIndex++; } } } } } if (termIndex < term.length) { return undefined; } if (curNode.constructor === Array) { return curNode; } else if (curNode["±"] !== undefined) { return curNode["±"]; } else { const arr = []; this.aggregateIndices(curNode, arr); return arr; } } aggregateIndices(curNode, arr) { for (const childNodeName in curNode) { const childNode = curNode[childNodeName]; if (childNode) { if (childNode.constructor === Array) { for (const num of childNode) { if (!arr.includes(num)) { arr.push(num); } } } else if (childNode["±"] !== undefined) { for (const num of childNode["±"]) { if (!arr.includes(num)) { arr.push(num); } } } else { this.aggregateIndices(childNode, arr); } } } } insertArray(key, items) { for (const item of items) { this.insert(key, item.value, item.annotation); } } insert(key, item, annotationChar) { if (Utilities_1.default.isNumericIsh(key) || key.length > 70) { return; } // since we treat ± as special, ban usage of ± in strings. key = key.replace(/±/gi, "").toLowerCase().trim(); let keyIndex = 0; let curNode = __classPrivateFieldGet(this, _ContentIndex_data, "f").trie; let parentNode = curNode; let curNodeIndex; let dataIndex = -1; let curIndex = 0; for (const itemCand of __classPrivateFieldGet(this, _ContentIndex_data, "f").items) { if (itemCand === item) { dataIndex = curIndex; break; } curIndex++; } if (dataIndex < 0) { dataIndex = __classPrivateFieldGet(this, _ContentIndex_data, "f").items.length; __classPrivateFieldGet(this, _ContentIndex_data, "f").items.push(item); } let hasAdvanced = true; while (keyIndex < key.length && hasAdvanced) { hasAdvanced = false; if (curNode.constructor !== Array) { for (const item in curNode) { // we've found part of our string in this node if (item.startsWith(key[keyIndex]) && curNode[item] !== undefined) { // && curNode[item].constructor !== Array) { let itemIndex = 0; hasAdvanced = true; curNodeIndex = item; parentNode = curNode; curNode = curNode[item]; while (keyIndex < key.length && itemIndex < item.length && item[itemIndex] === key[keyIndex]) { itemIndex++; keyIndex++; } // if we're in the middle of a string like "subset", and we're trying add the word "subpar", // create a new node called "sub" and place "set" underneath it. // also support the case where we're adding "sub" but "subset" already exists (keyIndex === key.length) if (item[itemIndex] !== key[keyIndex] && itemIndex < item.length && keyIndex <= key.length) { parentNode[curNodeIndex] = undefined; curNodeIndex = item.substring(0, itemIndex); let newNode = {}; parentNode[curNodeIndex] = newNode; const term = item.substring(itemIndex); if (!this._isTermToAvoid(term)) { newNode[term] = curNode; } curNode = newNode; } break; } } } } // we've reached the end of the trie; we need to add a new node if (keyIndex < key.length) { // if parent node was a leaf array, switch to an object if (curNode.constructor === Array && curNodeIndex) { parentNode[curNodeIndex] = {}; parentNode[curNodeIndex]["±"] = curNode; curNode = parentNode[curNodeIndex]; } const substr = key.substring(keyIndex); if (substr !== "±") { if (!this._isTermToAvoid(substr)) { // create a new leaf array curNode[substr] = this.ensureAnnotatedContentInArray([], dataIndex, annotationChar); } } } else { if (curNode.constructor === Array && curNodeIndex) { if (!this._isTermToAvoid(curNodeIndex)) { parentNode[curNodeIndex] = this.ensureAnnotatedContentInArray(curNode, dataIndex, annotationChar); } } else { if (curNode["±"] === undefined) { curNode["±"] = []; } curNode["±"] = this.ensureAnnotatedContentInArray(curNode["±"], dataIndex, annotationChar); } } } ensureAnnotatedContentInArray(arr, dataIndex, annotationChar) { try { for (const item of arr) { if (typeof item === "object") { if (item.n === dataIndex) { if (annotationChar) { if (!item.a) { item.a = annotationChar; } else { if (item.a.indexOf(annotationChar) < 0) { item.a += annotationChar; } } } return arr; } } else if (item === dataIndex) { if (!annotationChar) { return arr; } // convert simple number to annotated object const newArr = []; for (const existItem of arr) { if (existItem !== dataIndex) { newArr.push(existItem); } } newArr.push({ n: dataIndex, a: annotationChar }); return newArr; } } if (annotationChar) { arr.push({ n: dataIndex, a: annotationChar }); } else { arr.push(dataIndex); } } catch (e) { console.warn("Error ensuring annotated content: " + e + "|" + arr + "|" + JSON.stringify(arr)); } return arr; } parseJsContent(sourcePath, content) { try { const results = esprima_next_1.default.tokenize(content); if (results) { for (const token of results) { if (token.type === "Identifier" && token.value && token.value.length > 3) { if (token.value !== "from") { this.insert(token.value.toLowerCase(), sourcePath, "S"); } } } } } catch (e) { Log_1.default.debugAlert("JS parsing error:" + e); } } parseTextContent(sourcePath, content) { const dictionaryOfTerms = {}; let curWord = ""; content = content.toLowerCase(); for (let i = 0; i < content.length; i++) { const curChar = content[i]; if (curChar === "{" || curChar === "}" || curChar === " " || curChar === "\r" || curChar === "\n" || curChar === "\t" || curChar === "(" || curChar === ")" || curChar === "[" || curChar === "]" || curChar === ":" || curChar === '"' || curChar === "'") { if (curWord.length > 0) { if (curWord.length > 3 && !Utilities_1.default.isNumericIsh(curWord)) { dictionaryOfTerms[curWord] = true; } curWord = ""; } } else { curWord += content[i]; } } for (const term in dictionaryOfTerms) { this.insert(term, sourcePath); } } parseJsonContent(sourcePath, content) { const dictionaryOfTerms = {}; let curWord = ""; content = content.toLowerCase(); for (let i = 0; i < content.length; i++) { const curChar = content[i]; if (curChar === "{" || curChar === "}" || curChar === " " || curChar === "\r" || curChar === "\n" || curChar === "\t" || curChar === "(" || curChar === ")" || curChar === "[" || curChar === "]" || curChar === ":" || curChar === '"' || curChar === "'") { if (curWord.length > 0) { if (curWord.length > 3 && !Utilities_1.default.isNumericIsh(curWord)) { dictionaryOfTerms[curWord] = true; } curWord = ""; } } else { curWord += content[i]; } } for (const term in dictionaryOfTerms) { this.insert(term, sourcePath); } } } exports.default = ContentIndex; _ContentIndex_data = new WeakMap(), _ContentIndex_iteration = new WeakMap(); //# sourceMappingURL=../maps/core/ContentIndex.js.map