fix: encode ids as varints when exporting .schem

This commit is contained in:
trafficlunar 2025-01-22 22:03:58 +00:00
parent b5d3d75680
commit e6788d529a
2 changed files with 21 additions and 4 deletions

View file

@ -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: {

9
src/utils/varint.ts Normal file
View file

@ -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);
}