maintenance

This commit is contained in:
Holly Stubbs 2023-08-20 01:18:05 +01:00
parent 3123dac2c2
commit 79b1f0c0eb
Signed by: tgpholly
GPG Key ID: B8583C4B7D18119E
8 changed files with 46 additions and 26 deletions

View File

@ -1,7 +1,7 @@
{
"port": 25565,
"maxPlayers": 20,
"seed": "really janky",
"seed": "fuck you boltimore",
"saveCompression": "NONE",
"worldName": "world"
}

View File

@ -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
View File

@ -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"

View File

@ -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",

View File

@ -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;
}
}

View File

@ -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);
}

View File

@ -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}`);
}

View File

@ -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();