const fs = require("fs"); const path = require("path"); const settings = JSON.parse(fs.readFileSync("settings.json")); const recipesDir = "./recipes"; // 创建文件夹(如果不存在) function createDirIfNotExist(dirPath) { if (!fs.existsSync(dirPath)) { fs.mkdirSync(dirPath, { recursive: true }); } } // 写入 pack.mcmeta 文件 function writePackMcmeta() { const packMcmetaPath = "./recipes/pack.mcmeta"; const packContent = { pack: { description: "通用了部分整合包模组的物品", pack_format: 9, }, }; if (!fs.existsSync(packMcmetaPath)) { fs.writeFileSync( packMcmetaPath, JSON.stringify(packContent, null, 2), "utf8" ); console.log("创建并写入 pack.mcmeta 文件"); } } // 递归遍历文件夹并查找所有的 .json 文件 function traverseDir(dirPath) { const files = fs.readdirSync(dirPath); files.forEach((file) => { const filePath = path.join(dirPath, file); const stat = fs.statSync(filePath); if (stat.isDirectory()) { // 如果是文件夹,则递归调用 traverseDir(filePath); } else if (file.endsWith(".json")) { // 如果是 .json 文件,进行检查 checkJsonFile(filePath); } }); } // 遍历 JSON 内部的 key,替换内容 function traverseJson(obj, path) { const result = { replace: false, obj: Array.isArray(obj) ? [] : {} }; path = path !== undefined ? path : ""; for (let key in obj) { if (key === "result" || key === "results" || key === "output"){ result.obj[key] = obj[key]; continue; } if (typeof obj[key] === "object") { const returnedResult = traverseJson(obj[key], path + "." + key); result.replace = result.replace || returnedResult.replace; result.obj[key] = returnedResult.obj; continue; } if (key === "item"){ // Search item if (settings.enableSearch && settings.search && settings.search.items && settings.search.items.includes(obj[key])){ console.log(`[Item Found] ${path}.${key} 包含:${obj[key]}`); } // Replace if (settings.same){ const index = settings.same.findIndex((v) => v.list.includes(obj[key])); if (index >= 0){ console.log(`[Replace] ${path}.${key} 包含:${obj[key]}`); result.replace = true; result.obj["tag"] = settings.same[index].tag; continue; } } } else if (key === "tag"){ // Search tag if (settings.enableSearch && settings.search && settings.search.tags && settings.search.tags.includes(obj[key])){ console.log(`[Key Found] ${path}.${key} 包含:${obj[key]}`); } } result.obj[key] = obj[key]; } return result; } // 检查每个 .json 文件是否包含 "ingredients" 属性 function checkJsonFile(filePath) { try { const recipeJson = JSON.parse(fs.readFileSync(filePath, "utf8")); // if (!recipeJson["ingredients"] && !recipeJson["ingredient"] && !recipeJson["key"]) { // console.log(`未找到 "ingredients" 属性的文件: ${filePath}`); // } if ( recipeJson["result"] || recipeJson["results"] || recipeJson["output"] ) { // console.log(`文件: ${filePath}`); const result = traverseJson(recipeJson, `${filePath}$`); if (settings.enableGenerate && result.replace){ const writeFilePath = path.join(recipesDir, filePath); console.log(`[Replace] 正在写入文件:${writeFilePath}`); createDirIfNotExist(path.dirname(writeFilePath)); fs.writeFileSync(writeFilePath, JSON.stringify(result.obj, null, 2)); } } else { // console.log(`未找到 输出 属性的文件: ${filePath}`); } } catch (err) { console.error(`无法读取或解析文件: ${filePath}`); console.error(err); } } function generateTags(){ const recipesDataDir = path.join(recipesDir, "data"); createDirIfNotExist(recipesDir); // 确保 ./recipes 文件夹存在 writePackMcmeta(); // 确保 ./recipes/pack.mcmeta 文件存在 if (fs.existsSync(recipesDataDir)) { console.log(`正在清理 "${recipesDataDir}"`); fs.rmSync(recipesDataDir, { recursive: true, force: true }); } if (settings.same){ settings.same.forEach((ele) => { const splitedTag = ele.tag.split(":"); if (splitedTag.length !== 2){ console.error(`"${ele.tag}"格式不正确`); } const namespace = splitedTag[0]; const tagName = splitedTag[1]; const filePath = path.join(recipesDataDir, namespace, "tags/items/", tagName + ".json"); console.log(`正在写入文件:${filePath}`); createDirIfNotExist(path.dirname(filePath)); fs.writeFileSync(filePath, JSON.stringify({ replace: ele.replace, values: ele.list }, null, 2)); }); } } // 从 ./data 目录开始遍历 const dataDir = "./data"; if (settings.enableGenerate){ generateTags(); } traverseDir(dataDir);