From 86d17234ca2550c706e853a2a5bfc4888bfe061e Mon Sep 17 00:00:00 2001 From: holly Date: Tue, 10 Aug 2021 00:40:30 +0100 Subject: [PATCH] lol --- bufferStuff.js | 122 ++++++++++++++++++++++++++++++++++++++++ chunk.js | 67 ++++++++++++++++++++++ index.js | 149 +++++++++++++++++++++++++++++++++++++++++++++++++ nibbleArray.js | 46 +++++++++++++++ 4 files changed, 384 insertions(+) create mode 100644 bufferStuff.js create mode 100644 chunk.js create mode 100644 index.js create mode 100644 nibbleArray.js diff --git a/bufferStuff.js b/bufferStuff.js new file mode 100644 index 0000000..b045be8 --- /dev/null +++ b/bufferStuff.js @@ -0,0 +1,122 @@ +module.exports.Writer = class { + constructor() { + this.buffer = Buffer.alloc(0); + this.offset = 0; + } + + writeBuffer(buff = Buffer.alloc(0)) { + this.buffer = Buffer.concat([this.buffer, buff], this.buffer.length + buff.length); + } + + writeBool(data = false) { + this.writeByte(data ? 1 : 0); + } + + writeByte(data = 0) { + const buff = Buffer.alloc(1); + buff.writeInt8(data, 0); + + this.writeBuffer(buff); + } + + writeShort(data = 0) { + const buff = Buffer.alloc(2); + buff.writeIntBE(data, 0, 2); + + this.writeBuffer(buff); + } + + writeInt(data = 0) { + const buff = Buffer.alloc(4); + buff.writeIntBE(data, 0, 4); + + this.writeBuffer(buff); + } + + writeLong(data = 0) { + const buff = Buffer.alloc(8); + buff.writeBigInt64BE(BigInt(data), 0); + + this.writeBuffer(buff); + } + + writeFloat(data = 0.0) { + const buff = Buffer.alloc(4); + buff.writeFloatBE(data, 0); + + this.writeBuffer(buff); + } + + writeDouble(data = 0.0) { + const buff = Buffer.alloc(8); + buff.writeDoubleBE(data, 0); + + this.writeBuffer(buff); + } + + writeString(string = "") { + this.writeShort(string.length); + + for (let i = 0; i < string.length; i++) { + this.writeShort(string.charCodeAt(i)); + } + } +} + +module.exports.Reader = class { + constructor(buffer = Buffer.alloc(0)) { + this.buffer = buffer; + this.offset = 0; + } + + readBool() { + return this.readByte() == 0x01 ? true : false; + } + + readByte() { + const data = this.buffer.readInt8(this.offset); + this.offset += 1; + return data; + } + + readShort() { + const data = this.buffer.readIntBE(this.offset, 2); + this.offset += 2; + return data; + } + + readInt() { + const data = this.buffer.readIntBE(this.offset, 4); + this.offset += 4; + return data; + } + + readLong() { + const data = this.buffer.readBigInt64BE(this.offset); + this.offset += 8; + return data; + } + + readFloat() { + const data = this.buffer.readFloatBE(this.offset); + this.offset += 4; + return data; + } + + readDouble() { + const data = this.buffer.readDoubleBE(this.offset); + this.offset += 8; + return data; + } + + readString() { + const length = this.readShort(); + let data = ""; + + for (let i = 0; i < length; i++) { + data += String.fromCharCode(this.readShort()); + } + + return data; + } +} \ No newline at end of file diff --git a/chunk.js b/chunk.js new file mode 100644 index 0000000..01a7209 --- /dev/null +++ b/chunk.js @@ -0,0 +1,67 @@ +const nibbleArray = require("./nibbleArray.js"); + +module.exports = class { + constructor(xPos = 0, zPos = 0) { + this.xPos = xPos; + this.zPos = zPos; + + this.blocks = Buffer.alloc(256 * 128); + + this.data = new nibbleArray(this.blocks.length, 7); + + this.skylightMap = new nibbleArray(this.blocks.length, 7); + + this.blocklightMap = new nibbleArray(this.blocks.length, 7); + } + + getChunkData(xPos, yPos, zPos, l, i1, j1) { + let abyte0 = Buffer.alloc((l * i1 * j1 * 5) / 2); + let k1 = xPos >> 4; + let l1 = zPos >> 4; + let i2 = (xPos + l) - 1 >> 4; + let j2 = (zPos + j1) - 1 >> 4; + let k2 = 0; + let l2 = yPos; + let i3 = yPos + i1; + if(l2 < 0) + { + l2 = 0; + } + if(i3 > 128) + { + i3 = 128; + } + for(let j3 = k1; j3 <= i2; j3++) + { + let k3 = xPos - j3 * 16; + let l3 = (xPos + l) - j3 * 16; + if(k3 < 0) + { + k3 = 0; + } + if(l3 > 16) + { + l3 = 16; + } + for(let i4 = l1; i4 <= j2; i4++) + { + let j4 = k - i4 * 16; + let k4 = (k + j1) - i4 * 16; + if(j4 < 0) + { + j4 = 0; + } + if(k4 > 16) + { + k4 = 16; + } + k2 = getChunkFromChunkCoords(j3, i4).getChunkData(abyte0, k3, l2, j4, l3, i3, k4, k2); + } + + } + + return abyte0; + } + + +} \ No newline at end of file diff --git a/index.js b/index.js new file mode 100644 index 0000000..2830ad4 --- /dev/null +++ b/index.js @@ -0,0 +1,149 @@ +const net = require('net'); +const port = 25565; + +const { createGzip, deflate } = require("zlib"); + +const chunk = require("./chunk.js"); + +const myman = require("./bufferStuff.js"); + +const server = new net.Server(); + +const protocolVersion = 14; + +server.listen(port, function() { + console.log(`Server listening for connection requests on socket localhost:${port}`); +}); + +server.on('connection', function(socket) { + console.log('A new connection has been established.'); + + //socket.write('Hello, client.'); + + socket.on('data', function(chunk) { + //console.log(chunk); + + const reader = new myman.Reader(chunk); + + const id = reader.readByte(); + + console.log(`ID: ${id}`); + switch (id) { + case 0: + keepAlive(socket); + break; + + case 1: + loginRequest(socket, reader); + break; + + case 2: + handshake(socket, reader); + break; + + case 0x0B: + playerLook(socket, reader); + break; + } + }); + + socket.on('end', function() { + console.log('Closing connection with the client'); + }); + + socket.on('error', function(err) { + console.log(`Error: ${err}`); + }); +}); + +function keepAlive(socket) { + const writer = new myman.Writer(); + + writer.writeByte(0x00); + + socket.write(writer.buffer); +} + +function loginRequest(socket, reader = new myman.Reader) { + const proto = reader.readInt(); + const username = reader.readString(); + const mapSeed = reader.readLong(); + const dimension = reader.readByte(); + + console.log("Protocol Version: " + proto); + console.log("Username: " + username); + + const writer = new myman.Writer(); + + writer.writeByte(0x01); + + writer.writeInt(1); + writer.writeString(""); + writer.writeLong(971768181197178410); + writer.writeByte(0); + + socket.write(writer.buffer); + + writer.buffer = Buffer.alloc(0); + + writer.writeByte(0x06); + + writer.writeInt(0); + writer.writeInt(65); + writer.writeInt(0); + + socket.write(writer.buffer); + + preChunk(socket, 0, 0, true); +} + +function handshake(socket, reader = new myman.Reader) { + const username = reader.readString(); + + const writer = new myman.Writer(); + + writer.writeByte(0x02); + + writer.writeString("-"); + + socket.write(writer.buffer); +} + +function playerLook(socket, reader = new myman.Reader) { + const x = reader.readDouble(); + const y = reader.readDouble(); + const stance = reader.readDouble(); + const z = reader.readDouble(); + const onGround = reader.readBool(); + + /*console.log("X: " + x); + console.log("Y: " + y); + console.log("Z: " + z); + console.log("Stance: " + stance); + console.log("On Ground: " + onGround);*/ +} + +// Write + +function preChunk(socket, x, y, load = false) { + const writer = new myman.Writer(); + + writer.writeByte(0x32); + writer.writeInt(x); + writer.writeInt(y); + writer.writeBool(load); + + socket.write(writer.buffer); +} + +function writeChunk() { + const writer = new myman.Writer(); + + writer.writeByte(0x33); // ID + writer.writeInt(0); // Chunk X + writer.writeShort(0); // Chunk Y + writer.writeByte(15); // Chunk Z + writer.writeByte(127); // Chunk Size X + writer.writeByte(15); // Chunk Size Y + writer.writeInt(5); // Chunk Size Z +} \ No newline at end of file diff --git a/nibbleArray.js b/nibbleArray.js new file mode 100644 index 0000000..76ae3ca --- /dev/null +++ b/nibbleArray.js @@ -0,0 +1,46 @@ +module.exports = class { + constructor(i, j) { + if (i instanceof Buffer) { + this.data = abyte0; + this.field_35661_b = i; + this.field_35662_c = i + 4; + } else { + this.data = new Buffer.alloc(i >> 1); + this.field_35661_b = j; + this.field_35662_c = j + 4; + } + } + + getNibble(i, j, k) + { + let l = i << field_35662_c | k << field_35661_b | j; + let i1 = l >> 1; + let j1 = l & 1; + if(j1 == 0) + { + return data[i1] & 0xf; + } else + { + return data[i1] >> 4 & 0xf; + } + } + + setNibble(i, j, k, l) + { + let i1 = i << this.field_35662_c | k << this.field_35661_b | j; + let j1 = i1 >> 1; + let k1 = i1 & 1; + if(k1 == 0) + { + data[j1] = (this.data[j1] & 0xf0 | l & 0xf); + } else + { + data[j1] = (this.data[j1] & 0xf | (l & 0xf) << 4); + } + } + + isValid() + { + return this.data != null; + } +} \ No newline at end of file