diff --git a/bufferStuff.ts b/bufferStuff.ts index e67aae6..532e553 100644 --- a/bufferStuff.ts +++ b/bufferStuff.ts @@ -13,6 +13,7 @@ export class Reader { return value; } + // NOTE: This had to be a copy as the subarray is only cropped & offset public readUint8Array(bytes:number) { const croppedBuffer = this.readBuffer(bytes); const newArray = new Uint8Array(croppedBuffer.length); diff --git a/server/Chunk.ts b/server/Chunk.ts index 06383d7..42bb13e 100644 --- a/server/Chunk.ts +++ b/server/Chunk.ts @@ -20,20 +20,20 @@ export class Chunk { return (x >= 0 ? 0 : 2147483648) | (x & 0x7fff) << 16 | (z >= 0 ? 0 : 0x8000) | z & 0x7fff; } - public constructor(world:World, x:number, z:number, generateOrBlockData?:boolean|ArrayBuffer, metadata?:ArrayBuffer) { + public constructor(world:World, x:number, z:number, generateOrBlockData?:boolean|Uint8Array, metadata?:Uint8Array) { this.world = world; this.x = x; this.z = z; this.playersInChunk = new FunkyArray(); - if (generateOrBlockData instanceof ArrayBuffer && metadata instanceof ArrayBuffer) { + if (generateOrBlockData instanceof Uint8Array && metadata instanceof Uint8Array) { this.blocks = new Uint8Array(generateOrBlockData); this.metadata = new NibbleArray(metadata); } else { this.blocks = new Uint8Array(16 * 16 * this.MAX_HEIGHT); this.metadata = new NibbleArray(16 * 16 * this.MAX_HEIGHT); - if (generateOrBlockData) { + if (typeof(generateOrBlockData) === "boolean" && generateOrBlockData) { this.world.generator.generate(this); } } @@ -43,7 +43,7 @@ export class Chunk { if (x < 0 || x > 15 || y < 0 || y > 127 || z < 0 || z > 15) { return; } - + this.blocks[x << 11 | z << 7 | y] = blockId; } diff --git a/server/World.ts b/server/World.ts index efc6afd..c4318e1 100644 --- a/server/World.ts +++ b/server/World.ts @@ -96,7 +96,14 @@ export class World { const chunkX = x >> 4, chunkZ = z >> 4; - return this.getChunk(chunkX, chunkZ).getBlockId(x - chunkX << 4, y, z - chunkZ << 4); + return this.getChunk(chunkX, chunkZ).getBlockId(x & 0xf, y, z & 0xf); + } + + public getBlockMetadata(x:number, y:number, z:number) { + const chunkX = x >> 4, + chunkZ = z >> 4; + + return this.getChunk(chunkX, chunkZ).getBlockMetadata(x & 0xf, y, z & 0xf); } public setBlock(blockId:number, x:number, y:number, z:number, doBlockUpdate?:boolean) { @@ -104,10 +111,26 @@ export class World { chunkZ = z >> 4; const chunk = this.getChunk(chunkX, chunkZ); - chunk.setBlock(blockId, x - chunkX << 4, y, z - chunkZ << 4); + chunk.setBlockWithMetadata(blockId, 0, x & 0xf, y, z & 0xf); - const blockUpdatePacket = new PacketBlockChange(x, y, z, blockId, 0).writeData(); // TODO: Handle metadata if (doBlockUpdate) { + const blockUpdatePacket = new PacketBlockChange(x, y, z, blockId, 0).writeData(); + // Send block update to all players that have this chunk loaded + chunk.playersInChunk.forEach(player => { + player.mpClient?.send(blockUpdatePacket); + }); + } + } + + public setBlockWithMetadata(blockId:number, metadata:number, x:number, y:number, z:number, doBlockUpdate?:boolean) { + const chunkX = x >> 4, + chunkZ = z >> 4; + + const chunk = this.getChunk(chunkX, chunkZ); + chunk.setBlockWithMetadata(blockId, metadata, x & 0xf, y, z & 0xf); + + if (doBlockUpdate) { + const blockUpdatePacket = new PacketBlockChange(x, y, z, blockId, metadata).writeData(); // TODO: Handle metadata // Send block update to all players that have this chunk loaded chunk.playersInChunk.forEach(player => { player.mpClient?.send(blockUpdatePacket);