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 {
|
||||
Schematic: {
|
||||
Blocks: {
|
||||
Data: Int8Array;
|
||||
Data: Uint8Array;
|
||||
Palette: Record<string, number>;
|
||||
};
|
||||
DataVersion: number;
|
||||
|
|
@ -153,14 +153,15 @@ function OpenSchematic({ close }: DialogProps) {
|
|||
|
||||
// Add every block to the canvas
|
||||
const blocks: Block[] = [];
|
||||
let index = 0;
|
||||
let offset = 0;
|
||||
|
||||
for (let y = spongeData.Height; y > 0; y--) {
|
||||
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);
|
||||
|
||||
index++;
|
||||
offset += bytesRead;
|
||||
if (!paletteBlock) continue;
|
||||
|
||||
const blockIdWithProperties = paletteBlock.replace("minecraft:", "");
|
||||
|
|
|
|||
|
|
@ -1,9 +1,37 @@
|
|||
export function encodeVarint(number: number) {
|
||||
export function encodeVarint(number: number): Uint8Array {
|
||||
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)
|
||||
// Take 7 bits and set the MSB
|
||||
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);
|
||||
}
|
||||
|
||||
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