mc-beta-server/server/chunkManager.js

117 lines
3.1 KiB
JavaScript
Raw Normal View History

2021-08-12 04:58:56 +01:00
const FunkyArray = require("./Util/funkyArray.js");
const bufferStuff = require("./bufferStuff.js");
const config = require("../config.json");
const { Worker } = require('worker_threads');
2021-08-12 08:41:08 +01:00
const workerPath = __dirname + "/Workers/ChunkPacketGenerator.js";
2021-08-11 15:05:14 +01:00
module.exports = class {
constructor() {
2021-08-12 01:44:18 +01:00
this.chunks = {};
2021-08-12 04:58:56 +01:00
this.queuedBlockUpdates = new FunkyArray();
2021-08-12 08:41:08 +01:00
global.generatingChunks = true;
this.threadPool = [];
this.workPool = new FunkyArray();
this.toRemove = [];
2021-08-15 11:32:38 +01:00
// WoAh!!! Thread pool in js!?!??!???!11!?!?!
for (let i = 0; i < config.threadPoolCount; i++) {
2021-08-12 08:41:08 +01:00
const worker = new Worker(workerPath);
this.threadPool.push([false, worker]);
const myID = i;
worker.on("message", (data) => {
switch (data[0]) {
case "chunk":
const user = global.getUserByKey(data[2]);
user.chunksToSend.add(Buffer.from(data[1]));
break;
2021-08-15 11:32:38 +01:00
// Specific to the chunk task as multiple of them are sent before removal
case "remove":
this.toRemove.push(data[1]);
this.threadPool[myID][0] = false;
break;
2021-08-15 11:32:38 +01:00
case "generate":
this.chunks[data[2]][data[3]] = data[1];
this.toRemove.push(data[4]);
this.threadPool[myID][0] = false;
break;
}
2021-08-12 08:41:08 +01:00
});
}
console.log("Created thread pool with " + this.threadPool.length + " threads");
2021-08-12 08:41:08 +01:00
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][3] = key;
2021-08-12 08:41:08 +01:00
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);
2021-08-12 04:58:56 +01:00
for (let x = -3; x < 4; x++) {
for (let z = -3; z < 4; z++) {
this.createChunk(x, z);
}
}
2021-08-12 08:41:08 +01:00
global.generatingChunks = false;
2021-08-12 01:44:18 +01:00
}
2021-08-12 04:58:56 +01:00
// TODO: Store metadata!
createChunk(cx = 0, cz = 0) {
if (this.chunks[cx] == null) this.chunks[cx] = {};
this.workPool.add([false, ["generate", cx, cz, null]]);
2021-08-12 04:58:56 +01:00
}
multiBlockChunk(chunkX = 0, chunkZ = 0, user) {
this.workPool.add([false, ["chunk", [chunkX, chunkZ, this.chunks[chunkX][chunkZ]], user.id, null]]);
2021-08-12 04:58:56 +01:00
}
setBlock(id = 0, x = 0, y = 0, z = 0) {
if (y < 0 || y > 127) throw "Tried to set a block outside of the world!";
const chunkX = Math.floor(x / 16);
const chunkZ = Math.floor(z / 16);
const blockX = x - (16 * chunkX);
const blockZ = z - (16 * chunkZ);
// Don't queue a block update if that block is already this block
//if (this.chunks[chunkX][chunkZ][y][blockX][blockZ] == id) return;
2021-08-12 01:44:18 +01:00
2021-08-12 04:58:56 +01:00
this.queuedBlockUpdates.add([id, chunkX, chunkZ, y, blockX, blockZ]);
2021-08-11 15:05:14 +01:00
}
}