From 926db04a3e21f1d6035b4de36399be6cf0f3d4f6 Mon Sep 17 00:00:00 2001 From: HenryDu8133 <813367384@qq.com> Date: Sun, 16 Aug 2026 14:02:38 +0800 Subject: [PATCH] test: add block_reader NBT dumper for advanced display Reads the adjacent block (Advanced Display) via Advanced Peripherals block_reader and writes registry name, block state, and NBT data as structured text to blockreader_display_nbt.txt. --- test_blockreader_display.lua | 228 +++++++++++++++++++++++++++++++++++ 1 file changed, 228 insertions(+) create mode 100644 test_blockreader_display.lua diff --git a/test_blockreader_display.lua b/test_blockreader_display.lua new file mode 100644 index 0000000..1e819b5 --- /dev/null +++ b/test_blockreader_display.lua @@ -0,0 +1,228 @@ +-- BlockReader NBT Dumper for Advanced Display Block +-- Reads block NBT via Advanced Peripherals block_reader and writes to txt + +local COLORS = { + INFO = colors.white, + WARN = colors.yellow, + ERROR = colors.red, + SUCCESS = colors.green +} + +local OUTPUT_FILE = "blockreader_display_nbt.txt" + +local function log(level, message) + local timestamp = os.date("%H:%M:%S") + local logMessage = string.format("[%s][%s] %s", timestamp, level, message) + local color = COLORS[level] or colors.white + local oldColor = term.getTextColor() + term.setTextColor(color) + print(logMessage) + term.setTextColor(oldColor) +end + +local function serializeValue(value, indent) + indent = indent or 0 + local pad = string.rep(" ", indent) + + local t = type(value) + if t == "nil" then + return "nil" + elseif t == "boolean" then + return value and "true" or "false" + elseif t == "number" then + return tostring(value) + elseif t == "string" then + local escaped = value:gsub("\\", "\\\\"):gsub("\n", "\\n"):gsub("\r", "\\r"):gsub("\t", "\\t") + return string.format("%q", escaped) + elseif t == "table" then + local lines = {} + local isArray = true + local maxIndex = 0 + for k, v in pairs(value) do + if type(k) ~= "number" or k < 1 or math.floor(k) ~= k then + isArray = false + break + end + if k > maxIndex then maxIndex = k end + end + if isArray then + for i = 1, maxIndex do + if value[i] ~= nil then + table.insert(lines, pad .. " [" .. tostring(i) .. "] = " .. serializeValue(value[i], indent + 1)) + end + end + else + local keys = {} + for k, _ in pairs(value) do + table.insert(keys, k) + end + table.sort(keys, function(a, b) + local ta, tb = type(a), type(b) + if ta == tb then + if ta == "number" then return a < b end + return tostring(a) < tostring(b) + end + return ta < tb + end) + for _, k in ipairs(keys) do + local keyStr + if type(k) == "string" and k:match("^[%a_][%w_]*$") then + keyStr = k + else + keyStr = "[" .. serializeValue(k, 0) .. "]" + end + local v = value[k] + if type(v) == "table" and next(v) ~= nil then + table.insert(lines, pad .. " " .. keyStr .. " = {") + table.insert(lines, serializeValue(v, indent + 1)) + table.insert(lines, pad .. " }") + else + table.insert(lines, pad .. " " .. keyStr .. " = " .. serializeValue(v, indent + 1)) + end + end + end + if #lines == 0 then + return "{}" + end + if isArray then + return table.concat(lines, "\n") + end + table.insert(lines, 1, pad .. "{") + table.insert(lines, pad .. "}") + return table.concat(lines, "\n") + else + return "<" .. t .. ">" + end +end + +local function findBlockReader() + local readers = { peripheral.find("blockReader") } + if #readers > 0 then + return readers[1], peripheral.getName(readers[1]) + end + for _, side in ipairs(rs.getSides()) do + if peripheral.isPresent(side) and peripheral.getType(side) == "blockReader" then + return peripheral.wrap(side), side + end + end + local names = peripheral.getNames() + for _, name in ipairs(names) do + if peripheral.getType(name) == "blockReader" then + return peripheral.wrap(name), name + end + end + return nil, nil +end + +local function writeToFile(content) + local handle = fs.open(OUTPUT_FILE, "w") + if not handle then + return false, "Cannot open output file" + end + handle.write(content) + handle.close() + return true, nil +end + +local function main() + term.clear() + term.setCursorPos(1, 1) + print("=== BlockReader Advanced Display NBT Dumper ===") + print("Output file: " .. OUTPUT_FILE) + print() + + log("INFO", "Looking for block_reader peripheral...") + local reader, readerName = findBlockReader() + if not reader then + log("ERROR", "block_reader not found. Connect a block_reader Advanced Peripheral to the computer.") + return 1 + end + log("SUCCESS", "block_reader found: " .. tostring(readerName)) + + if type(reader.isBlockPresent) ~= "function" then + log("WARN", "isBlockPresent() not available on this block_reader, trying direct read...") + else + local ok, present = pcall(function() return reader.isBlockPresent() end) + if ok and not present then + log("ERROR", "No block in front of block_reader. Place the Advanced Display block adjacent to the block_reader.") + return 2 + end + end + + local output = {} + table.insert(output, "Advanced Display Block NBT Dump") + table.insert(output, "Generated: " .. os.date("%Y-%m-%d %H:%M:%S")) + table.insert(output, "BlockReader: " .. tostring(readerName)) + table.insert(output, string.rep("=", 60)) + table.insert(output, "") + + if type(reader.getBlockName) == "function" then + local ok, name = pcall(function() return reader.getBlockName() end) + if ok and name then + table.insert(output, "[Block Registry Name]") + table.insert(output, " " .. tostring(name)) + table.insert(output, "") + end + end + + if type(reader.getBlockState) == "function" then + local ok, state = pcall(function() return reader.getBlockState() end) + if ok and state then + table.insert(output, "[Block State]") + if type(state) == "table" and next(state) == nil then + table.insert(output, " (empty)") + else + table.insert(output, serializeValue(state, 0)) + end + table.insert(output, "") + end + end + + if type(reader.getBlockData) == "function" then + local ok, data = pcall(function() return reader.getBlockData() end) + if ok and data then + table.insert(output, "[Block NBT Data]") + if type(data) == "table" and next(data) == nil then + table.insert(output, " (empty)") + else + table.insert(output, serializeValue(data, 0)) + end + table.insert(output, "") + else + log("WARN", "getBlockData() failed or returned nothing: " .. tostring(data)) + end + else + log("WARN", "getBlockData() not found on this block_reader") + end + + local fullContent = table.concat(output, "\n") + local ok, err = writeToFile(fullContent) + if not ok then + log("ERROR", "Failed to write file: " .. tostring(err)) + return 3 + end + + log("SUCCESS", "NBT data written to " .. OUTPUT_FILE) + local size = fs.getSize(OUTPUT_FILE) + log("INFO", "File size: " .. tostring(size) .. " bytes") + + print() + print("Press any key to exit...") + os.pullEvent("key") + return 0 +end + +local exitCode = 0 +local ok, err = pcall(main) +if not ok then + log("ERROR", "Program crashed: " .. tostring(err)) + exitCode = 99 +end + +if exitCode ~= 0 then + print() + print("Press any key to exit...") + os.pullEvent("key") +end + +error("", exitCode)