fsdfdsf
This commit is contained in:
parent
c7a65b0dfa
commit
e51415766c
3 changed files with 191 additions and 55 deletions
71
server/Workers/ChunkPacketGenerator.js
Normal file
71
server/Workers/ChunkPacketGenerator.js
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
const { Worker, MessageChannel, MessagePort, isMainThread, parentPort } = require('worker_threads');
|
||||||
|
|
||||||
|
const bufferStuff = require("../bufferStuff.js");
|
||||||
|
|
||||||
|
let chunkY = 0;
|
||||||
|
let busyInterval = null;
|
||||||
|
|
||||||
|
parentPort.on("message", (chunk) => {
|
||||||
|
if (busyInterval == null) {
|
||||||
|
busyInterval = setInterval(() => {}, 86400000);
|
||||||
|
}
|
||||||
|
|
||||||
|
chunkY = 0;
|
||||||
|
// I couldn't figure out how to construct a chunk lmao
|
||||||
|
// __ima just send each block individually__
|
||||||
|
// Using multi block chunks now!
|
||||||
|
// TODO: yknow, figure out how to chunk.
|
||||||
|
let chunksToSend = [];
|
||||||
|
|
||||||
|
chunksToSend.push(doSquareChunk(chunk));
|
||||||
|
chunkY += 16;
|
||||||
|
chunksToSend.push(doSquareChunk(chunk));
|
||||||
|
chunkY += 16;
|
||||||
|
chunksToSend.push(doSquareChunk(chunk));
|
||||||
|
chunkY += 16;
|
||||||
|
chunksToSend.push(doSquareChunk(chunk));
|
||||||
|
chunkY += 16;
|
||||||
|
chunksToSend.push(doSquareChunk(chunk));
|
||||||
|
chunkY += 16;
|
||||||
|
chunksToSend.push(doSquareChunk(chunk));
|
||||||
|
chunkY += 16;
|
||||||
|
chunksToSend.push(doSquareChunk(chunk));
|
||||||
|
chunkY += 16;
|
||||||
|
chunksToSend.push(doSquareChunk(chunk));
|
||||||
|
|
||||||
|
parentPort.postMessage([chunk[3], chunksToSend, chunk[4], chunk[5]]);
|
||||||
|
});
|
||||||
|
|
||||||
|
function doSquareChunk(chunk) {
|
||||||
|
let blocksToSend = [];
|
||||||
|
for (let y = 0; y < 16; y++) {
|
||||||
|
for (let x = 0; x < 16; x++) {
|
||||||
|
for (let z = 0; z < 16; z++) {
|
||||||
|
if (chunk[2][chunkY + y][x][z] == 0) continue; // don't send air lol
|
||||||
|
blocksToSend.push([chunk[2][chunkY + y][x][z], x & 0xf, z & 0xf, chunkY + y]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const writer = new bufferStuff.Writer();
|
||||||
|
writer.writeByte(0x34);
|
||||||
|
writer.writeInt(chunk[0]);
|
||||||
|
writer.writeInt(chunk[1]);
|
||||||
|
writer.writeShort(blocksToSend.length);
|
||||||
|
// Block coords
|
||||||
|
for (let blocks of blocksToSend) {
|
||||||
|
writer.writeShort((blocks[1] << 12 | blocks[2] << 8 | blocks[3]) - 32768);
|
||||||
|
}
|
||||||
|
// Block types
|
||||||
|
for (let blocks of blocksToSend) {
|
||||||
|
writer.writeByte(blocks[0]);
|
||||||
|
}
|
||||||
|
// Block metadata
|
||||||
|
for (let blocks of blocksToSend) {
|
||||||
|
writer.writeByte(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
//user.chunksToSend.add(writer.buffer) // so we don't flood the client queue these
|
||||||
|
//parentPort.postMessage(writer.buffer);
|
||||||
|
return writer.buffer;
|
||||||
|
}
|
|
@ -1,17 +1,77 @@
|
||||||
const FunkyArray = require("./Util/funkyArray.js");
|
const FunkyArray = require("./Util/funkyArray.js");
|
||||||
const bufferStuff = require("./bufferStuff.js");
|
const bufferStuff = require("./bufferStuff.js");
|
||||||
|
|
||||||
|
const { Worker, isMainThread, parentPort } = require('worker_threads');
|
||||||
|
|
||||||
|
const workerPath = __dirname + "/Workers/ChunkPacketGenerator.js";
|
||||||
|
|
||||||
module.exports = class {
|
module.exports = class {
|
||||||
constructor() {
|
constructor() {
|
||||||
this.chunks = {};
|
this.chunks = {};
|
||||||
|
|
||||||
this.queuedBlockUpdates = new FunkyArray();
|
this.queuedBlockUpdates = new FunkyArray();
|
||||||
|
|
||||||
|
global.generatingChunks = true;
|
||||||
|
|
||||||
|
this.threadPool = [];
|
||||||
|
this.workPool = new FunkyArray();
|
||||||
|
|
||||||
|
this.toRemove = [];
|
||||||
|
|
||||||
|
for (let i = 0; i < 6; i++) {
|
||||||
|
const worker = new Worker(workerPath);
|
||||||
|
this.threadPool.push([false, worker]);
|
||||||
|
const myID = i;
|
||||||
|
worker.on("message", (message) => {
|
||||||
|
const user = global.getUserByKey(message[0]);
|
||||||
|
for (let square of message[1]) { user.chunksToSend.add(Buffer.from(square)); }
|
||||||
|
this.threadPool[myID][0] = false;
|
||||||
|
this.toRemove.push(message[2]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
setInterval(() => {
|
||||||
|
if (this.workPool.getLength() > 0) {
|
||||||
|
let limit = Math.min(this.workPool.getLength(), this.threadPool.length);
|
||||||
|
for (let i = 0; i < limit; i++) {
|
||||||
|
for (let i1 = 0; i1 < this.threadPool.length; i1++) {
|
||||||
|
let thread = this.threadPool[i1];
|
||||||
|
if (!thread[0]) {
|
||||||
|
const key = this.workPool.itemKeys[i];
|
||||||
|
const item = this.workPool.getByKey(key);
|
||||||
|
// Already being processed
|
||||||
|
if (item == null) break;
|
||||||
|
if (item[0] == true) {
|
||||||
|
limit += 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
item[0] = true;
|
||||||
|
item[1][4] = key;
|
||||||
|
item[1][5] = i1;
|
||||||
|
thread[1].postMessage(item[1]);
|
||||||
|
thread[0] = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let item of this.toRemove) {
|
||||||
|
//console.log("removing item " + this.workPool.getByKey(item)[0]);
|
||||||
|
this.workPool.remove(item);
|
||||||
|
}
|
||||||
|
this.toRemove = [];
|
||||||
|
}
|
||||||
|
}, 1000 / 20);
|
||||||
|
|
||||||
|
const chunkStartTime = new Date().getTime();
|
||||||
for (let x = -3; x < 4; x++) {
|
for (let x = -3; x < 4; x++) {
|
||||||
for (let z = -3; z < 4; z++) {
|
for (let z = -3; z < 4; z++) {
|
||||||
this.createChunk(x, z);
|
this.createChunk(x, z);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
console.log("Chunk generation took " + (new Date().getTime() - chunkStartTime) + "ms");
|
||||||
|
|
||||||
|
global.generatingChunks = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Store metadata!
|
// TODO: Store metadata!
|
||||||
|
@ -24,12 +84,13 @@ module.exports = class {
|
||||||
for (let y = 0; y < 128; y++) {
|
for (let y = 0; y < 128; y++) {
|
||||||
this.chunks[cx][cz][y] = {};
|
this.chunks[cx][cz][y] = {};
|
||||||
for (let x = 0; x < 16; x++) {
|
for (let x = 0; x < 16; x++) {
|
||||||
this.chunks[cx][cz][y][x] = [];
|
this.chunks[cx][cz][y][x] = {};
|
||||||
for (let z = 0; z < 16; z++) {
|
for (let z = 0; z < 16; z++) {
|
||||||
if (y == 64) {
|
if (y == 64) {
|
||||||
this.chunks[cx][cz][y][x].push(2);
|
|
||||||
// Make a tree :)
|
// Make a tree :)
|
||||||
if (Math.random() <= 0.01) {
|
if (Math.random() <= 0.01) {
|
||||||
|
this.chunks[cx][cz][y][x][z] = 3;
|
||||||
|
|
||||||
const newX = x + (16 * cx), newZ = z + (16 * cz);
|
const newX = x + (16 * cx), newZ = z + (16 * cz);
|
||||||
// trunk
|
// trunk
|
||||||
this.setBlock(17, newX, y + 1, newZ);
|
this.setBlock(17, newX, y + 1, newZ);
|
||||||
|
@ -37,61 +98,25 @@ module.exports = class {
|
||||||
this.setBlock(17, newX, y + 3, newZ);
|
this.setBlock(17, newX, y + 3, newZ);
|
||||||
this.setBlock(17, newX, y + 4, newZ);
|
this.setBlock(17, newX, y + 4, newZ);
|
||||||
// leaves
|
// leaves
|
||||||
this.setBlock(18, newX + 2, y + 3, newZ + 2);
|
// left
|
||||||
this.setBlock(18, newX + 1, y + 3, newZ + 2);
|
this.setBlock(18, newX, y + 5, newZ);
|
||||||
this.setBlock(18, newX, y + 3, newZ + 2);
|
// right line
|
||||||
this.setBlock(18, newX - 1, y + 3, newZ + 2);
|
} else {
|
||||||
this.setBlock(18, newX - 2, y + 3, newZ + 2);
|
this.chunks[cx][cz][y][x][z] = 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (y == 63 || y == 62) this.chunks[cx][cz][y][x].push(3);
|
else if (y == 63 || y == 62) this.chunks[cx][cz][y][x][z] = 3;
|
||||||
else if (y == 0) this.chunks[cx][cz][y][x].push(7);
|
else if (y == 0) this.chunks[cx][cz][y][x][z] = 7;
|
||||||
else if (y < 62) this.chunks[cx][cz][y][x].push(1);
|
else if (y < 62) this.chunks[cx][cz][y][x][z] = 1;
|
||||||
else this.chunks[cx][cz][y][x].push(0);
|
else this.chunks[cx][cz][y][x][z] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
multiBlockChunk(chunkX = 0, chunkZ = 0, user) {
|
async multiBlockChunk(chunkX = 0, chunkZ = 0, user) {
|
||||||
const writer = new bufferStuff.Writer();
|
//worker.postMessage([chunkX, chunkZ, this.chunks[chunkX][chunkZ]]);
|
||||||
|
this.workPool.add([false, [chunkX, chunkZ, this.chunks[chunkX][chunkZ], user.id, null, null]]);
|
||||||
// I couldn't figure out how to construct a chunk lmao
|
|
||||||
// __ima just send each block individually__
|
|
||||||
// Using multi block chunks now!
|
|
||||||
// TODO: yknow, figure out how to chunk.
|
|
||||||
let blocksToSend = [];
|
|
||||||
for (let y = 0; y < 128; y++) {
|
|
||||||
blocksToSend = [];
|
|
||||||
for (let x = 0; x < 16; x++) {
|
|
||||||
for (let z = 0; z < 16; z++) {
|
|
||||||
if (this.chunks[chunkX][chunkZ][y][x][z] == 0) continue; // don't send air lol
|
|
||||||
blocksToSend.push([this.chunks[chunkX][chunkZ][y][x][z], x & 0xf, z & 0xf]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (blocksToSend.length > 0) {
|
|
||||||
writer.reset();
|
|
||||||
writer.writeByte(0x34);
|
|
||||||
writer.writeInt(chunkX);
|
|
||||||
writer.writeInt(chunkZ);
|
|
||||||
writer.writeShort(blocksToSend.length);
|
|
||||||
// Block coords
|
|
||||||
for (let blocks of blocksToSend) {
|
|
||||||
writer.writeShort((blocks[1] << 12 | blocks[2] << 8 | y) - 32768);
|
|
||||||
}
|
|
||||||
// Block types
|
|
||||||
for (let blocks of blocksToSend) {
|
|
||||||
writer.writeByte(blocks[0]);
|
|
||||||
}
|
|
||||||
// Block metadata
|
|
||||||
for (let blocks of blocksToSend) {
|
|
||||||
writer.writeByte(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
user.chunksToSend.add(writer.buffer) // so we don't flood the client queue these
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setBlock(id = 0, x = 0, y = 0, z = 0) {
|
setBlock(id = 0, x = 0, y = 0, z = 0) {
|
||||||
|
|
|
@ -17,6 +17,10 @@ global.fromIDPool = function() {
|
||||||
let netUsers = {},
|
let netUsers = {},
|
||||||
netUserKeys = Object.keys(netUsers);
|
netUserKeys = Object.keys(netUsers);
|
||||||
|
|
||||||
|
global.getUserByKey = function(key) {
|
||||||
|
return netUsers[key];
|
||||||
|
}
|
||||||
|
|
||||||
function addUser(socket) {
|
function addUser(socket) {
|
||||||
let user = new User(global.fromIDPool(), socket);
|
let user = new User(global.fromIDPool(), socket);
|
||||||
netUsers[user.id] = user;
|
netUsers[user.id] = user;
|
||||||
|
@ -25,8 +29,9 @@ function addUser(socket) {
|
||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeUser() {
|
function removeUser(id) {
|
||||||
|
delete netUsers[id];
|
||||||
|
netUserKeys = Object.keys(netUsers);
|
||||||
}
|
}
|
||||||
|
|
||||||
let config = {};
|
let config = {};
|
||||||
|
@ -34,6 +39,7 @@ let config = {};
|
||||||
let entities = {};
|
let entities = {};
|
||||||
|
|
||||||
global.chunkManager = new ChunkManager();
|
global.chunkManager = new ChunkManager();
|
||||||
|
global.generatingChunks = false;
|
||||||
|
|
||||||
let tickInterval, tickCounter = BigInt(0);
|
let tickInterval, tickCounter = BigInt(0);
|
||||||
let tickRate = BigInt(20);
|
let tickRate = BigInt(20);
|
||||||
|
@ -43,11 +49,36 @@ module.exports.init = function(config) {
|
||||||
console.log(`Up! Running at 0.0.0.0:${config.port}`);
|
console.log(`Up! Running at 0.0.0.0:${config.port}`);
|
||||||
|
|
||||||
tickInterval = setInterval(() => {
|
tickInterval = setInterval(() => {
|
||||||
|
// Update Chunks
|
||||||
|
if (!global.generatingChunks) {
|
||||||
|
let itemsToRemove = [];
|
||||||
|
for (let i = 0; i < Math.min(global.chunkManager.queuedBlockUpdates.getLength(), 128); i++) {
|
||||||
|
const chunkUpdateKey = global.chunkManager.queuedBlockUpdates.itemKeys[i];
|
||||||
|
const chunkUpdate = global.chunkManager.queuedBlockUpdates.items[chunkUpdateKey];
|
||||||
|
itemsToRemove.push(chunkUpdateKey);
|
||||||
|
|
||||||
|
try {
|
||||||
|
global.chunkManager.chunks[chunkUpdate[1]][chunkUpdate[2]][chunkUpdate[3]][chunkUpdate[4]][chunkUpdate[5]] = chunkUpdate[0];
|
||||||
|
|
||||||
|
const packet = new PacketMappingTable[NamedPackets.BlockChange](chunkUpdate[4] + (16 * chunkUpdate[1]), chunkUpdate[3], chunkUpdate[5] + (16 * chunkUpdate[2]), chunkUpdate[0]).writePacket();
|
||||||
|
for (let userKey in netUserKeys) {
|
||||||
|
const user = netUsers[userKey];
|
||||||
|
if (user.loginFinished) user.socket.write(packet);
|
||||||
|
}
|
||||||
|
} catch (e) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let item of itemsToRemove) {
|
||||||
|
global.chunkManager.queuedBlockUpdates.remove(item, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update users
|
||||||
for (let key of netUserKeys) {
|
for (let key of netUserKeys) {
|
||||||
const user = netUsers[netUserKeys];
|
const user = netUsers[netUserKeys];
|
||||||
|
|
||||||
let itemsToRemove = [];
|
let itemsToRemove = [];
|
||||||
for (let i = 0; i < Math.min(user.chunksToSend.getLength(), 128); i++) {
|
for (let i = 0; i < Math.min(user.chunksToSend.getLength(), 32); i++) {
|
||||||
const chunkKey = user.chunksToSend.itemKeys[i];
|
const chunkKey = user.chunksToSend.itemKeys[i];
|
||||||
itemsToRemove.push(chunkKey);
|
itemsToRemove.push(chunkKey);
|
||||||
user.socket.write(user.chunksToSend.items[chunkKey]);
|
user.socket.write(user.chunksToSend.items[chunkKey]);
|
||||||
|
@ -64,7 +95,7 @@ module.exports.init = function(config) {
|
||||||
}, 1000 / parseInt(tickRate.toString()));
|
}, 1000 / parseInt(tickRate.toString()));
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports.connection = function(socket = new Socket) {
|
module.exports.connection = async function(socket = new Socket) {
|
||||||
const thisUser = addUser(socket);
|
const thisUser = addUser(socket);
|
||||||
|
|
||||||
socket.on('data', function(chunk) {
|
socket.on('data', function(chunk) {
|
||||||
|
@ -79,12 +110,13 @@ module.exports.connection = function(socket = new Socket) {
|
||||||
socket.write(new PacketMappingTable[NamedPackets.LoginRequest](reader.readInt(), reader.readString(), reader.readLong(), reader.readByte()).writePacket(thisUser.id));
|
socket.write(new PacketMappingTable[NamedPackets.LoginRequest](reader.readInt(), reader.readString(), reader.readLong(), reader.readByte()).writePacket(thisUser.id));
|
||||||
socket.write(new PacketMappingTable[NamedPackets.SpawnPosition]().writePacket());
|
socket.write(new PacketMappingTable[NamedPackets.SpawnPosition]().writePacket());
|
||||||
|
|
||||||
|
const dt = new Date().getTime();
|
||||||
for (let x = -3; x < 4; x++) {
|
for (let x = -3; x < 4; x++) {
|
||||||
for (let z = -3; z < 4; z++) {
|
for (let z = -3; z < 4; z++) {
|
||||||
socket.write(new PacketMappingTable[NamedPackets.PreChunk](x, z, true).writePacket());
|
socket.write(new PacketMappingTable[NamedPackets.PreChunk](x, z, true).writePacket());
|
||||||
global.chunkManager.multiBlockChunk(x, z, thisUser);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
console.log("Chunk packet generation took " + (new Date().getTime() - dt) + "ms");
|
||||||
socket.write(new PacketMappingTable[NamedPackets.BlockChange](8, 64, 8, 20, 0).writePacket());
|
socket.write(new PacketMappingTable[NamedPackets.BlockChange](8, 64, 8, 20, 0).writePacket());
|
||||||
|
|
||||||
socket.write(new PacketMappingTable[NamedPackets.Player](true).writePacket());
|
socket.write(new PacketMappingTable[NamedPackets.Player](true).writePacket());
|
||||||
|
@ -94,6 +126,12 @@ module.exports.connection = function(socket = new Socket) {
|
||||||
socket.write(new PacketMappingTable[NamedPackets.PlayerPositionAndLook](8.5, 65 + 1.6200000047683716, 65, 8.5, 0, 0, false).writePacket());
|
socket.write(new PacketMappingTable[NamedPackets.PlayerPositionAndLook](8.5, 65 + 1.6200000047683716, 65, 8.5, 0, 0, false).writePacket());
|
||||||
|
|
||||||
thisUser.loginFinished = true;
|
thisUser.loginFinished = true;
|
||||||
|
|
||||||
|
for (let x = -3; x < 4; x++) {
|
||||||
|
for (let z = -3; z < 4; z++) {
|
||||||
|
global.chunkManager.multiBlockChunk(x, z, thisUser);
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NamedPackets.Handshake:
|
case NamedPackets.Handshake:
|
||||||
|
@ -106,9 +144,11 @@ module.exports.connection = function(socket = new Socket) {
|
||||||
|
|
||||||
socket.on('end', function() {
|
socket.on('end', function() {
|
||||||
console.log("Connection closed");
|
console.log("Connection closed");
|
||||||
|
removeUser(thisUser.id);
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.on('error', function(err) {
|
socket.on('error', function(err) {
|
||||||
console.log("Connection error!");
|
console.log("Connection error!");
|
||||||
|
removeUser(thisUser.id);
|
||||||
});
|
});
|
||||||
}
|
}
|
Loading…
Reference in a new issue