maintenance
This commit is contained in:
parent
3123dac2c2
commit
79b1f0c0eb
8 changed files with 46 additions and 26 deletions
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"port": 25565,
|
||||
"maxPlayers": 20,
|
||||
"seed": "really janky",
|
||||
"seed": "fuck you boltimore",
|
||||
"saveCompression": "NONE",
|
||||
"worldName": "world"
|
||||
}
|
|
@ -57,7 +57,7 @@ export class FunkyArray<T, TT> {
|
|||
}
|
||||
|
||||
public forEach(callback: (value:TT) => void) {
|
||||
return new Promise<boolean>((resolve, reject) => {
|
||||
return new Promise<boolean>(async (resolve, reject) => {
|
||||
if (this.items.size === 0) {
|
||||
return resolve(true);
|
||||
}
|
||||
|
@ -66,7 +66,7 @@ export class FunkyArray<T, TT> {
|
|||
const iterator = this.items.values();
|
||||
let result:IteratorResult<TT, TT>;
|
||||
while (!(result = iterator.next()).done) {
|
||||
callback(result.value);
|
||||
await callback(result.value);
|
||||
}
|
||||
resolve(true);
|
||||
} catch (e) {
|
||||
|
|
16
package-lock.json
generated
16
package-lock.json
generated
|
@ -13,8 +13,8 @@
|
|||
"hsconsole": "^1.0.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^20.4.5",
|
||||
"check-outdated": "^2.11.0",
|
||||
"@types/node": "^20.5.0",
|
||||
"check-outdated": "^2.12.0",
|
||||
"nodemon": "^3.0.1",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"terser": "^5.19.2",
|
||||
|
@ -170,9 +170,9 @@
|
|||
"peer": true
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "20.4.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.4.5.tgz",
|
||||
"integrity": "sha512-rt40Nk13II9JwQBdeYqmbn2Q6IVTA5uPhvSO+JVqdXw/6/4glI6oR9ezty/A9Hg5u7JH4OmYmuQ+XvjKm0Datg==",
|
||||
"version": "20.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.0.tgz",
|
||||
"integrity": "sha512-Mgq7eCtoTjT89FqNoTzzXg2XvCi5VMhRV6+I2aYanc6kQCBImeNaAYRs/DyoVqk1YEUJK5gN9VO7HRIdz4Wo3Q==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@webassemblyjs/ast": {
|
||||
|
@ -605,9 +605,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/check-outdated": {
|
||||
"version": "2.11.0",
|
||||
"resolved": "https://registry.npmjs.org/check-outdated/-/check-outdated-2.11.0.tgz",
|
||||
"integrity": "sha512-YZmbRlpWCi2plPRpKLNPJLeel+86qvHMK1Tt9Dpt/APjtSCDrI9YpMvXr4lGrsx8aH0QJev7VJUyfcfwKQ/CCg==",
|
||||
"version": "2.12.0",
|
||||
"resolved": "https://registry.npmjs.org/check-outdated/-/check-outdated-2.12.0.tgz",
|
||||
"integrity": "sha512-kWThJFiqxAE09XSNJLLD4hWNvLhWdxFLKxOHhxB+XhGlZGyeELXP8V6R/dRrZ5vbjmp9VmoTYe0vp6egftKz7Q==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"check-outdated": "check-outdated.js"
|
||||
|
|
|
@ -29,8 +29,8 @@
|
|||
"hsconsole": "^1.0.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^20.4.5",
|
||||
"check-outdated": "^2.11.0",
|
||||
"@types/node": "^20.5.0",
|
||||
"check-outdated": "^2.12.0",
|
||||
"nodemon": "^3.0.1",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"terser": "^5.19.2",
|
||||
|
|
|
@ -57,6 +57,8 @@ export class Chunk {
|
|||
public getTopBlockY(x:number, z:number) {
|
||||
let castY = this.MAX_HEIGHT;
|
||||
while (castY-- > 0) {
|
||||
const blockId = this.getBlockId(x >>> 0, castY, z >>> 0);
|
||||
console.log(blockId === 0 ? "Air" : Block.blocks[blockId].blockName);
|
||||
if (this.getBlockId(x >>> 0, castY, z >>> 0) !== 0) {
|
||||
break;
|
||||
}
|
||||
|
@ -161,7 +163,7 @@ export class Chunk {
|
|||
return this.metadata.toBuffer();
|
||||
}
|
||||
|
||||
public getData() {
|
||||
public getBlockData() {
|
||||
return this.blocks;
|
||||
}
|
||||
}
|
|
@ -67,6 +67,7 @@ export class MPClient {
|
|||
//case Packets.UseBed: break;
|
||||
case Packet.Animation: this.handlePacketAnimation(new PacketAnimation().readData(reader)); break;
|
||||
case Packet.EntityAction: this.handlePacketEntityAction(new PacketEntityAction().readData(reader)); break;
|
||||
case Packet.DisconnectKick: this.handleDisconnectKick(); break;
|
||||
default: Console.printWarn(`UNIMPLEMENTED PACKET: ${Packet[packetId]}`); break;
|
||||
}
|
||||
}
|
||||
|
@ -79,15 +80,12 @@ export class MPClient {
|
|||
this.send(new PacketPlayerPositionLook(parseFloat(message[1]), parseFloat(message[2]), parseFloat(message[2]) + 0.62, parseFloat(message[3]), 0, 0, false).writeData());
|
||||
Console.printInfo(packet.message = `Teleported ${this.entity.username} to ${message[1]} ${message[2]} ${message[3]}`);
|
||||
} else if (message[0] === "/csay") {
|
||||
const consoleMessage = `[CONSOLE] ${message.slice(1, message.length).join(" ")}`;
|
||||
Console.printInfo(`[CHAT] ${consoleMessage}`);
|
||||
this.mcServer.sendToAllClients(new PacketChat(consoleMessage).writeData());
|
||||
this.mcServer.sendChatMessage(`[CONSOLE] ${message.slice(1, message.length).join(" ")}`);
|
||||
} else if (message[0] === "/top") {
|
||||
// TODO: Figure out why this is broken
|
||||
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 PacketPlayerPosition(this.entity.x, topBlock + 4, topBlock + 4.62, this.entity.z, false).writeData());
|
||||
this.send(new PacketPlayerPosition(this.entity.x, topBlock + 3, topBlock + 3.62, this.entity.z, false).writeData());
|
||||
}
|
||||
|
||||
if (packet.message !== "") {
|
||||
|
@ -159,6 +157,10 @@ export class MPClient {
|
|||
}
|
||||
}
|
||||
|
||||
private handleDisconnectKick() {
|
||||
this.socket.end();
|
||||
}
|
||||
|
||||
public send(buffer:Buffer) {
|
||||
this.socket.write(buffer);
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ import { SaveCompressionType } from "./enums/SaveCompressionType";
|
|||
import { WorldSaveManager } from "./WorldSaveManager";
|
||||
import { World } from "./World";
|
||||
import { Chunk } from "./Chunk";
|
||||
import { PacketTimeUpdate } from "./packets/TimeUpdate";
|
||||
|
||||
export class MinecraftServer {
|
||||
private static readonly PROTOCOL_VERSION = 14;
|
||||
|
@ -27,7 +28,7 @@ export class MinecraftServer {
|
|||
|
||||
private config:Config;
|
||||
private server:Server;
|
||||
private readonly serverClock:NodeJS.Timer;
|
||||
private readonly serverClock:NodeJS.Timeout;
|
||||
private tickCounter:number = 0;
|
||||
private clients:FunkyArray<string, MPClient>;
|
||||
private worlds:FunkyArray<number, World>;
|
||||
|
@ -52,7 +53,12 @@ export class MinecraftServer {
|
|||
public constructor(config:Config) {
|
||||
this.config = config;
|
||||
|
||||
let shuttingDown = false;
|
||||
process.on("SIGINT", async (signal) => {
|
||||
if (shuttingDown) {
|
||||
return;
|
||||
}
|
||||
shuttingDown = true;
|
||||
Console.printInfo("Shutting down...");
|
||||
// Stop the server timer
|
||||
clearInterval(this.serverClock);
|
||||
|
@ -63,6 +69,7 @@ export class MinecraftServer {
|
|||
this.server.close();
|
||||
// Save chunks
|
||||
Console.printInfo("Saving worlds...");
|
||||
// There's a race condition here. oops.
|
||||
let savedWorldCount = 0;
|
||||
let savedChunkCount = 0;
|
||||
await this.worlds.forEach(async (world) => {
|
||||
|
@ -118,9 +125,10 @@ export class MinecraftServer {
|
|||
(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);
|
||||
for (let x = -5; x < 5; x++) {
|
||||
for (let z = -5; z < 5; z++) {
|
||||
const chunk = await this.overworld.getChunkSafe(x, z);
|
||||
chunk.forceLoaded = true;
|
||||
}
|
||||
}
|
||||
Console.printInfo(`Done! Took ${Date.now() - generateStartTime}ms`);
|
||||
|
@ -130,8 +138,11 @@ export class MinecraftServer {
|
|||
// Every 1 sec
|
||||
if (this.tickCounter % MinecraftServer.TICK_RATE === 0) {
|
||||
if (this.clients.length !== 0) {
|
||||
const timePacket = new PacketTimeUpdate(BigInt(this.tickCounter)).writeData();
|
||||
this.clients.forEach(client => {
|
||||
// Keep the client happy
|
||||
client.send(this.keepalivePacket);
|
||||
client.send(timePacket);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -153,6 +164,11 @@ export class MinecraftServer {
|
|||
});
|
||||
}
|
||||
|
||||
sendChatMessage(text:string) {
|
||||
this.sendToAllClients(new PacketChat(text).writeData());
|
||||
Console.printInfo(`[CHAT] ${text}`);
|
||||
}
|
||||
|
||||
handleLoginRequest(reader:IReader, socket:Socket, setMPClient:(mpclient:MPClient) => void) {
|
||||
const loginPacket = new PacketLoginRequest().readData(reader);
|
||||
if (loginPacket.protocolVersion !== MinecraftServer.PROTOCOL_VERSION) {
|
||||
|
@ -174,7 +190,7 @@ export class MinecraftServer {
|
|||
clientEntity.mpClient = client;
|
||||
this.clients.set(loginPacket.username, client);
|
||||
|
||||
this.sendToAllClients(new PacketChat(`\u00a7e${loginPacket.username} joined the game`).writeData());
|
||||
this.sendChatMessage(`\u00a7e${loginPacket.username} joined the game`);
|
||||
|
||||
socket.write(new PacketLoginRequest(clientEntity.entityId, "", 0, 0).writeData());
|
||||
socket.write(new PacketSpawnPosition(8, 64, 8).writeData());
|
||||
|
@ -207,7 +223,7 @@ export class MinecraftServer {
|
|||
const playerDisconnect = (err:Error) => {
|
||||
mpClient.entity.world.removeEntity(mpClient.entity);
|
||||
this.clients.remove(mpClient.entity.username);
|
||||
this.sendToAllClients(new PacketChat(`\u00a7e${mpClient.entity.username} left the game`).writeData());
|
||||
this.sendChatMessage(`\u00a7e${mpClient.entity.username} left the game`);
|
||||
if (typeof(err) !== "boolean") {
|
||||
Console.printError(`Client disconnected with error: ${err.message}`);
|
||||
}
|
||||
|
|
|
@ -98,7 +98,7 @@ export class WorldSaveManager {
|
|||
chunkFileWriter.writeUByte(16); // Chunk Z
|
||||
|
||||
const chunkData = createWriter(Endian.BE)
|
||||
.writeBuffer(Buffer.from(chunk.getData()))
|
||||
.writeBuffer(Buffer.from(chunk.getBlockData()))
|
||||
.writeBuffer(chunk.getMetadataBuffer())
|
||||
.writeBuffer(chunk.getBlockLightBuffer())
|
||||
.writeBuffer(chunk.getSkyLightBuffer()).toBuffer();
|
||||
|
|
Loading…
Reference in a new issue