fix: decoding varint for .schem files
This commit is contained in:
parent
6ab167e7db
commit
6779713897
2 changed files with 37 additions and 8 deletions
|
|
@ -37,7 +37,7 @@ interface LitematicNBT extends nbt.ListTagLike {
|
||||||
interface SpongeNBT extends nbt.ListTagLike {
|
interface SpongeNBT extends nbt.ListTagLike {
|
||||||
Schematic: {
|
Schematic: {
|
||||||
Blocks: {
|
Blocks: {
|
||||||
Data: Int8Array;
|
Data: Uint8Array;
|
||||||
Palette: Record<string, number>;
|
Palette: Record<string, number>;
|
||||||
};
|
};
|
||||||
DataVersion: number;
|
DataVersion: number;
|
||||||
|
|
@ -153,14 +153,15 @@ function OpenSchematic({ close }: DialogProps) {
|
||||||
|
|
||||||
// Add every block to the canvas
|
// Add every block to the canvas
|
||||||
const blocks: Block[] = [];
|
const blocks: Block[] = [];
|
||||||
let index = 0;
|
let offset = 0;
|
||||||
|
|
||||||
for (let y = spongeData.Height; y > 0; y--) {
|
for (let y = spongeData.Height; y > 0; y--) {
|
||||||
for (let x = 0; x < spongeData.Width; x++) {
|
for (let x = 0; x < spongeData.Width; x++) {
|
||||||
const paletteValue = spongeData.Blocks.Data[index];
|
// Decode varint to get the pallete value
|
||||||
|
const { value: paletteValue, bytesRead } = decodeVarint(spongeData.Blocks.Data, offset);
|
||||||
const paletteBlock = Object.keys(spongeData.Blocks.Palette).find((key) => spongeData.Blocks.Palette[key] == paletteValue);
|
const paletteBlock = Object.keys(spongeData.Blocks.Palette).find((key) => spongeData.Blocks.Palette[key] == paletteValue);
|
||||||
|
|
||||||
index++;
|
offset += bytesRead;
|
||||||
if (!paletteBlock) continue;
|
if (!paletteBlock) continue;
|
||||||
|
|
||||||
const blockIdWithProperties = paletteBlock.replace("minecraft:", "");
|
const blockIdWithProperties = paletteBlock.replace("minecraft:", "");
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,37 @@
|
||||||
export function encodeVarint(number: number) {
|
export function encodeVarint(number: number): Uint8Array {
|
||||||
const result = [];
|
const result = [];
|
||||||
while (number >= 0x80) {
|
while (number >= 0x80) {
|
||||||
result.push((number & 0x7f) | 0x80); // Take 7 bits and set the MSB
|
// Take 7 bits and set the MSB
|
||||||
number >>>= 7; // Right shift by 7 bits (logical shift)
|
result.push((number & 0x7f) | 0x80);
|
||||||
|
|
||||||
|
// Right shift by 7 bits (logical shift)
|
||||||
|
number >>>= 7;
|
||||||
}
|
}
|
||||||
result.push(number); // Last byte without MSB set
|
|
||||||
|
// Last byte without MSB set
|
||||||
|
result.push(number);
|
||||||
return new Uint8Array(result);
|
return new Uint8Array(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function decodeVarint(buffer: Uint8Array, offset: number): { value: number; bytesRead: number } {
|
||||||
|
let value = 0;
|
||||||
|
let position = 0;
|
||||||
|
let byte: number;
|
||||||
|
|
||||||
|
do {
|
||||||
|
if (position > 35) {
|
||||||
|
throw new Error("VarInt is too big");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read the current byte
|
||||||
|
byte = buffer[offset++];
|
||||||
|
|
||||||
|
// Extract the lower 7 bits of the byte and shift them to the correct position
|
||||||
|
value |= (byte & 0x7f) << (position * 7);
|
||||||
|
|
||||||
|
// Increment the position for the next byte
|
||||||
|
position++;
|
||||||
|
} while ((byte & 0x80) !== 0); // Continue if the most significant bit (MSB) is set
|
||||||
|
|
||||||
|
return { value, bytesRead: position };
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue