From 3b208eb8db45f30fd1e8428ba1fc7fdaf7df4f27 Mon Sep 17 00:00:00 2001 From: Holly Date: Mon, 19 Jun 2023 18:29:16 +0100 Subject: [PATCH] lighting sort of works --- config.json | 3 +-- config.ts | 1 - server/Chunk.ts | 30 ++++++++++++------------- server/MPClient.ts | 2 +- server/MinecraftServer.ts | 12 +++++++++- server/World.ts | 7 ++++-- server/WorldSaveManager.ts | 19 +++++++++------- server/blocks/Block.ts | 45 +++++++++++++++++++++++++------------- server/generators/Hilly.ts | 7 +++--- server/packets/MapChunk.ts | 6 ++--- 10 files changed, 80 insertions(+), 52 deletions(-) diff --git a/config.json b/config.json index a65479e..4a17294 100644 --- a/config.json +++ b/config.json @@ -1,8 +1,7 @@ { "port": 25565, - "onlineMode": false, "maxPlayers": 20, "seed": "really janky", - "saveCompression": "DEFLATE", + "saveCompression": "NONE", "worldName": "world" } \ No newline at end of file diff --git a/config.ts b/config.ts index 04237f9..de7d7f9 100644 --- a/config.ts +++ b/config.ts @@ -2,7 +2,6 @@ import { SaveCompressionType } from "./server/enums/SaveCompressionType"; export interface Config { port: number, - onlineMode: boolean, maxPlayers: number, seed: number|string, worldName: string, diff --git a/server/Chunk.ts b/server/Chunk.ts index 8fb4aca..a5bf3e7 100644 --- a/server/Chunk.ts +++ b/server/Chunk.ts @@ -1,3 +1,4 @@ +import { Console } from "../console"; import { FunkyArray } from "../funkyArray"; import { NibbleArray } from "../nibbleArray"; import { Block } from "./blocks/Block"; @@ -40,7 +41,7 @@ export class Chunk { this.metadata = new NibbleArray(metadata); this.skyLight = new NibbleArray(16 * 16 * this.MAX_HEIGHT); this.blockLight = new NibbleArray(16 * 16 * this.MAX_HEIGHT); - //this.calculateLighting(); + this.calculateLighting(); } else { this.blocks = new Uint8Array(16 * 16 * this.MAX_HEIGHT); this.metadata = new NibbleArray(16 * 16 * this.MAX_HEIGHT); @@ -49,7 +50,7 @@ export class Chunk { if (typeof(generateOrBlockData) === "boolean" && generateOrBlockData) { this.world.generator.generate(this); - //this.calculateLighting(); + this.calculateLighting(); } } } @@ -57,7 +58,7 @@ export class Chunk { public getTopBlockY(x:number, z:number) { let castY = this.MAX_HEIGHT; while (castY-- > 0) { - if (this.getBlockId(x, castY, z) !== 0) { + if (this.getBlockId(x >>> 0, castY, z >>> 0) !== 0) { break; } } @@ -66,10 +67,10 @@ export class Chunk { public calculateLighting() { let blockId = 0; - for (let y = 0; y < 128; y++) { - let colLight = 255; - for (let x = 0; x < 16; x++) { - for (let z = 0; z < 16; z++) { + for (let x = 0; x < 16; x++) { + for (let z = 0; z < 16; z++) { + let colLight = 255; + for (let y = this.MAX_HEIGHT - 1; y > 0; y--) { blockId = this.getBlockId(x, y, z); if (blockId == 0) { if (colLight <= 0) { @@ -79,16 +80,15 @@ export class Chunk { this.setBlockLight(Math.round((colLight / 255) * 15), x, y, z); this.setSkyLight(Math.round((colLight / 255) * 15), x, y, z); } - continue; - } - - if (colLight <= 0) { - this.setBlockLight(0, x, y, z); } else { - this.setBlockLight(Math.round((colLight / 255) * 15), x, y, z); - colLight -= (255 - Block.blocks[blockId].lightPassage); + if (colLight <= 0) { + this.setBlockLight(0, x, y, z); + } else { + this.setBlockLight(Math.round((colLight / 255) * 15), x, y, z); + colLight -= (255 - Block.blocks[blockId].lightPassage); + } } - } + } } } } diff --git a/server/MPClient.ts b/server/MPClient.ts index 74642ac..870a87b 100644 --- a/server/MPClient.ts +++ b/server/MPClient.ts @@ -87,7 +87,7 @@ export class MPClient { packet.message = `Woosh!`; const topBlock = this.entity.world.getChunk(this.entity.x >> 4, this.entity.z >> 4).getTopBlockY(this.entity.x & 0xf, this.entity.z & 0xf); console.log(topBlock); - this.send(new PacketPlayerPositionLook(this.entity.x, topBlock, topBlock + 0.62, this.entity.z, this.entity.yaw, this.entity.pitch, false).writeData()); + this.send(new PacketPlayerPosition(this.entity.x, topBlock + 4, topBlock + 4.62, this.entity.z, false).writeData()); } if (packet.message !== "") { diff --git a/server/MinecraftServer.ts b/server/MinecraftServer.ts index cb26aa4..f908edf 100644 --- a/server/MinecraftServer.ts +++ b/server/MinecraftServer.ts @@ -75,7 +75,7 @@ export class MinecraftServer { this.worlds.set(0, this.overworld = new World(this.saveManager, worldSeed)); // Generate spawn area (overworld) - (async () => { + /*(async () => { const generateStartTime = Date.now(); Console.printInfo("Generating spawn area..."); for (let x = -3; x < 3; x++) { @@ -84,6 +84,16 @@ export class MinecraftServer { } } Console.printInfo(`Done! Took ${Date.now() - generateStartTime}ms`); + }).bind(this)();*/ + (async () => { + const generateStartTime = Date.now(); + Console.printInfo("Generating spawn area..."); + for (let x = 0; x < 1; x++) { + for (let z = 0; z < 1; z++) { + await this.overworld.getChunkSafe(x, z); + } + } + Console.printInfo(`Done! Took ${Date.now() - generateStartTime}ms`); }).bind(this)(); this.serverClock = setInterval(() => { diff --git a/server/World.ts b/server/World.ts index 0e3d722..1655abc 100644 --- a/server/World.ts +++ b/server/World.ts @@ -12,6 +12,7 @@ import { IQueuedUpdate } from "./queuedUpdateTypes/IQueuedUpdate"; export class World { public static ENTITY_MAX_SEND_DISTANCE = 50; + private static READ_CHUNKS_FROM_DISK = false; private readonly saveManager; @@ -84,7 +85,7 @@ export class World { const coordPair = Chunk.CreateCoordPair(x, z); const existingChunk = this.chunks.get(coordPair); if (!(existingChunk instanceof Chunk)) { - if (this.saveManager.chunksOnDisk.includes(coordPair)) { + if (World.READ_CHUNKS_FROM_DISK && this.saveManager.chunksOnDisk.includes(coordPair)) { return this.saveManager.readChunkFromDisk(this, x, z) .then(chunk => { //console.log("Loaded " + x + "," + z + " from disk"); @@ -92,7 +93,9 @@ export class World { }); } else { resolve(this.chunks.set(coordPair, new Chunk(this, x, z, true))); - this.saveManager.writeChunkToDisk(this.getChunk(x, z)); + if (World.READ_CHUNKS_FROM_DISK) { + this.saveManager.writeChunkToDisk(this.getChunk(x, z)); + } return; } } diff --git a/server/WorldSaveManager.ts b/server/WorldSaveManager.ts index ec033ac..2f47ce0 100644 --- a/server/WorldSaveManager.ts +++ b/server/WorldSaveManager.ts @@ -87,12 +87,15 @@ export class WorldSaveManager { } public writeChunkToDisk(chunk:Chunk) { + return new Promise((resolve, reject) => { + resolve(false); + }); return new Promise((resolve, reject) => { const saveType = this.config.saveCompression; const chunkFileWriter = createWriter(Endian.BE, 10); chunkFileWriter.writeUByte(0xFC); // Chunk File Magic // TODO: Change to 1 when lighting actually works - chunkFileWriter.writeUByte(0); // File Version + chunkFileWriter.writeUByte(1); // File Version chunkFileWriter.writeUByte(saveType); // Save compression type chunkFileWriter.writeUByte(16); // Chunk X chunkFileWriter.writeUByte(128); // Chunk Y @@ -100,15 +103,15 @@ export class WorldSaveManager { const chunkData = createWriter(Endian.BE) .writeBuffer(Buffer.from(chunk.getData())) - .writeBuffer(chunk.getMetadataBuffer()).toBuffer() - //.writeBuffer(chunk.getBlockLightBuffer()) - //.writeBuffer(chunk.getSkyLightBuffer()).toBuffer(); + .writeBuffer(chunk.getMetadataBuffer()) + .writeBuffer(chunk.getBlockLightBuffer()) + .writeBuffer(chunk.getSkyLightBuffer()).toBuffer(); if (saveType === SaveCompressionType.NONE) { chunkFileWriter.writeInt(chunkData.length); // Data length chunkFileWriter.writeBuffer(chunkData); // Chunk data - writeFile(`${this.worldChunksFolderPath}/${Chunk.CreateCoordPair(chunk.x, chunk.z)}.hwc`, chunkFileWriter.toBuffer(), () => { + writeFile(`${this.worldChunksFolderPath}/${Chunk.CreateCoordPair(chunk.x, chunk.z).toString(16)}.hwc`, chunkFileWriter.toBuffer(), () => { const cPair = Chunk.CreateCoordPair(chunk.x, chunk.z); if (!this.chunksOnDisk.includes(cPair)) { this.chunksOnDisk.push(cPair); @@ -125,7 +128,7 @@ export class WorldSaveManager { chunkFileWriter.writeInt(data.length); chunkFileWriter.writeBuffer(data); - writeFile(`${this.worldChunksFolderPath}/${Chunk.CreateCoordPair(chunk.x, chunk.z)}.hwc`, chunkFileWriter.toBuffer(), () => { + writeFile(`${this.worldChunksFolderPath}/${Chunk.CreateCoordPair(chunk.x, chunk.z).toString(16)}.hwc`, chunkFileWriter.toBuffer(), () => { const cPair = Chunk.CreateCoordPair(chunk.x, chunk.z); if (!this.chunksOnDisk.includes(cPair)) { this.chunksOnDisk.push(cPair); @@ -142,7 +145,7 @@ export class WorldSaveManager { readChunkFromDisk(world:World, x:number, z:number) { return new Promise((resolve, reject) => { - readFile(`${this.worldChunksFolderPath}/${Chunk.CreateCoordPair(x, z)}.hwc`, (err, data) => { + readFile(`${this.worldChunksFolderPath}/${Chunk.CreateCoordPair(x, z).toString(16)}.hwc`, (err, data) => { if (err) { return reject(err); } @@ -188,7 +191,7 @@ export class WorldSaveManager { const contentLength = chunkFileReader.readInt(); if (saveCompressionType === SaveCompressionType.NONE) { const chunkData = createReader(Endian.BE, chunkFileReader.readBuffer(contentLength)); - const chunk = new Chunk(world, x, z, chunkData.readUint8Array(totalByteSize), chunkData.readUint8Array(totalByteSize / 2)); + const chunk = new Chunk(world, x, z, chunkData.readUint8Array(totalByteSize), chunkData.readUint8Array(totalByteSize / 2), chunkData.readUint8Array(totalByteSize / 2), chunkData.readUint8Array(totalByteSize / 2)); resolve(chunk); } else if (saveCompressionType === SaveCompressionType.DEFLATE) { inflate(chunkFileReader.readBuffer(contentLength), (err, data) => { diff --git a/server/blocks/Block.ts b/server/blocks/Block.ts index 06cf09d..0d3e594 100644 --- a/server/blocks/Block.ts +++ b/server/blocks/Block.ts @@ -2,10 +2,12 @@ export class Block { public readonly blockId:number; public static readonly blocks:Array = new Array(); public static readonly lightPassage:Array = new Array(); + public static readonly blockNames:Array = new Array(); public constructor(blockId:number) { Block.blocks[blockId] = this; Block.lightPassage[blockId] = 0; + Block.blockNames[blockId] = ""; this.blockId = blockId; } @@ -17,34 +19,47 @@ export class Block { Block.lightPassage[this.blockId] = value; } + public get blockName() { + return Block.blockNames[this.blockId]; + } + + public set blockName(value:string) { + Block.blockNames[this.blockId] = value; + } + public setLightPassage(value:number) { this.lightPassage = value; return this; } + public setBlockName(value:string) { + this.blockName = value; + return this; + } + // Define statics here - static readonly stone = new Block(1); - static readonly grass = new Block(2); - static readonly dirt = new Block(3); + static readonly stone = new Block(1).setBlockName("Stone"); + static readonly grass = new Block(2).setBlockName("Grass"); + static readonly dirt = new Block(3).setBlockName("Dirt"); - static readonly bedrock = new Block(7); + static readonly bedrock = new Block(7).setBlockName("Bedrock"); - static readonly waterStill = new Block(9).setLightPassage(3); + static readonly waterStill = new Block(9).setLightPassage(128).setBlockName("Still Water"); - static readonly lavaStill = new Block(11); + static readonly lavaStill = new Block(11).setBlockName("Still Lava"); - static readonly sand = new Block(12); - static readonly gravel = new Block(13); + static readonly sand = new Block(12).setBlockName("Sand"); + static readonly gravel = new Block(13).setBlockName("Gravel"); - static readonly wood = new Block(17); - static readonly leaves = new Block(18).setLightPassage(1); + static readonly wood = new Block(17).setBlockName("Wood"); + static readonly leaves = new Block(18).setLightPassage(240).setBlockName("Leaves"); - static readonly glass = new Block(20).setLightPassage(255); + static readonly glass = new Block(20).setLightPassage(255).setBlockName("Glass"); - static readonly tallGrass = new Block(31); + static readonly tallGrass = new Block(31).setLightPassage(255).setBlockName("Tall Grass"); - static readonly flowerDandelion = new Block(37); - static readonly flowerRose = new Block(38); + static readonly flowerDandelion = new Block(37).setLightPassage(255).setBlockName("Dandelion"); + static readonly flowerRose = new Block(38).setLightPassage(255).setBlockName("Rose"); - static readonly clay = new Block(82); + static readonly clay = new Block(82).setBlockName("Clay"); } \ No newline at end of file diff --git a/server/generators/Hilly.ts b/server/generators/Hilly.ts index c33cc62..ebc7ca4 100644 --- a/server/generators/Hilly.ts +++ b/server/generators/Hilly.ts @@ -24,6 +24,7 @@ export class HillyGenerator implements IGenerator { private caveGenerator3:Noise3D; private caveGenerator4:Noise3D; private caveGenerator5:Noise3D; + private caveGenerator6:Noise3D; private underwaterGravelGenerator:Noise2D; private underwaterSandGenerator:Noise2D; @@ -49,13 +50,12 @@ export class HillyGenerator implements IGenerator { this.caveGenerator3 = this.createGenerator3D(); this.caveGenerator4 = this.createGenerator3D(); this.caveGenerator5 = this.createGenerator3D(); + this.caveGenerator6 = this.createGenerator3D(); this.underwaterGravelGenerator = this.createGenerator2D(); this.underwaterSandGenerator = this.createGenerator2D(); this.underwaterClayGenerator = this.createGenerator2D(); this.flowerGenerator = this.createGenerator2D(); - - } private createGenerator2D() { @@ -144,8 +144,7 @@ export class HillyGenerator implements IGenerator { ((this.caveGenerator1((chunk.x * 16 + x) / 16, caveY / 16, (chunk.z * 16 + z) / 16) + this.caveGenerator2((chunk.x * 16 + x) / 8, caveY / 8, (chunk.z * 16 + z) / 8)) / 2) > 0.45 || this.caveGenerator3((chunk.x * 16 + x) / 16, caveY / 16, (chunk.z * 16 + z) / 16) > 0.6 || - this.caveGenerator4((chunk.x * 16 + x) / 16, caveY / 16, (chunk.z * 16 + z) / 16) > 0.6 || - this.caveGenerator5((chunk.x * 16 + x) / 16, caveY / 16, (chunk.z * 16 + z) / 16) > 0.5 + this.caveGenerator4((chunk.x * 16 + x) / 8, caveY / 8, (chunk.z * 16 + z) / 8) > 0.6 ) { if (caveY <= 3) { chunk.setBlock(Block.lavaStill.blockId, x, caveY, z); diff --git a/server/packets/MapChunk.ts b/server/packets/MapChunk.ts index 691b65e..0fac4a9 100644 --- a/server/packets/MapChunk.ts +++ b/server/packets/MapChunk.ts @@ -36,12 +36,12 @@ export class PacketMapChunk implements IPacket { public writeData() { return new Promise((resolve, reject) => { // TODO: Use block and sky nibble array buffers - const fakeLighting = createWriter(Endian.BE, 16384); + /*const fakeLighting = createWriter(Endian.BE, 16384); for (let i = 0; i < 16384; i++) { fakeLighting.writeUByte(0xFF); - } + }*/ - const data = createWriter(Endian.BE).writeBuffer(this.chunk.getBlockBuffer()).writeBuffer(this.chunk.getMetadataBuffer()).writeBuffer(fakeLighting.toBuffer()).writeBuffer(fakeLighting.toBuffer());//.writeBuffer(this.chunk.blockLight.toBuffer()).writeBuffer(this.chunk.skyLight.toBuffer()); + const data = createWriter(Endian.BE).writeBuffer(this.chunk.getBlockBuffer()).writeBuffer(this.chunk.getMetadataBuffer()).writeBuffer(this.chunk.blockLight.toBuffer()).writeBuffer(this.chunk.skyLight.toBuffer());//.writeBuffer(fakeLighting.toBuffer()).writeBuffer(fakeLighting.toBuffer()); deflate(data.toBuffer(), (err, data) => { if (err) {