From e6788d529a7817e161cd371ba1bcad231fe01d8d Mon Sep 17 00:00:00 2001 From: trafficlunar Date: Wed, 22 Jan 2025 22:03:58 +0000 Subject: [PATCH] fix: encode ids as varints when exporting .schem --- src/components/dialogs/SaveSchem.tsx | 16 ++++++++++++---- src/utils/varint.ts | 9 +++++++++ 2 files changed, 21 insertions(+), 4 deletions(-) create mode 100644 src/utils/varint.ts diff --git a/src/components/dialogs/SaveSchem.tsx b/src/components/dialogs/SaveSchem.tsx index 922f775..8e3a57d 100644 --- a/src/components/dialogs/SaveSchem.tsx +++ b/src/components/dialogs/SaveSchem.tsx @@ -4,6 +4,8 @@ import * as nbt from "nbtify"; import { CanvasContext } from "@/context/Canvas"; import { LoadingContext } from "@/context/Loading"; +import { encodeVarint } from "@/utils/varint"; + import { DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from "@/components/ui/dialog"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; @@ -103,10 +105,9 @@ function SaveLitematic({ close }: DialogProps) { }, {}); // Get the block data - const buffer = new ArrayBuffer(filledBlocks.length); - const blockPlaceData = new Int8Array(buffer); + const ids: number[] = []; - filledBlocks.forEach((block, index) => { + filledBlocks.forEach((block) => { const blockInfo = blockData[block.name.replace("minecraft:", "")]; const blockName = blockInfo ? blockInfo.id : block.name; const properties = blockInfo.properties @@ -116,9 +117,16 @@ function SaveLitematic({ close }: DialogProps) { : ""; const blockId = blockPalette[`minecraft:${blockName}${properties}`]; - blockPlaceData[index] = parseInt(blockId.toString()); + // Parse blockId to number then encode as varint + const id = encodeVarint(parseInt(blockId.toString())); + // Push to separate array to make array buffer + ids.push(...id); }); + const buffer = new ArrayBuffer(ids.length); + const blockPlaceData = new Uint8Array(buffer); + blockPlaceData.set(ids); + // Generate NBT data const data = { Schematic: { diff --git a/src/utils/varint.ts b/src/utils/varint.ts new file mode 100644 index 0000000..27d5888 --- /dev/null +++ b/src/utils/varint.ts @@ -0,0 +1,9 @@ +export function encodeVarint(number: number) { + const result = []; + while (number >= 0x80) { + result.push((number & 0x7f) | 0x80); // Take 7 bits and set the MSB + number >>>= 7; // Right shift by 7 bits (logical shift) + } + result.push(number); // Last byte without MSB set + return new Uint8Array(result); +}