From b371521fda0d5d25605193a9d42d0c3ebf72e494 Mon Sep 17 00:00:00 2001 From: Holly Date: Mon, 10 Apr 2023 21:52:30 +0100 Subject: [PATCH] Animations & Metadata --- server/MPClient.ts | 61 ++++++++++++++++++--- server/MetadataWriter.ts | 69 ++++++++++++++++++++++++ server/MinecraftServer.ts | 12 ++--- server/Vec3.ts | 6 +++ server/World.ts | 24 +++++++++ server/entities/Entity.ts | 43 +++++++++++++++ server/entities/EntityLiving.ts | 4 +- server/entities/IEntity.ts | 2 + server/enums/Animation.ts | 9 ++++ server/enums/MetadataFieldType.ts | 9 ++++ server/enums/{Packets.ts => Packet.ts} | 7 ++- server/packets/Animation.ts | 30 +++++++++++ server/packets/BlockChange.ts | 42 +++++++++++++++ server/packets/Chat.ts | 4 +- server/packets/DisconnectKick.ts | 4 +- server/packets/Entity.ts | 4 +- server/packets/EntityAction.ts | 30 +++++++++++ server/packets/EntityEquipment.ts | 4 +- server/packets/EntityLook.ts | 4 +- server/packets/EntityLookRelativeMove.ts | 4 +- server/packets/EntityMetadata.ts | 31 +++++++++++ server/packets/EntityRelativeMove.ts | 4 +- server/packets/EntityTeleport.ts | 4 +- server/packets/Handshake.ts | 4 +- server/packets/IPacket.ts | 4 +- server/packets/KeepAlive.ts | 6 +-- server/packets/LoginRequest.ts | 4 +- server/packets/MapChunk.ts | 4 +- server/packets/NamedEntitySpawn.ts | 4 +- server/packets/Player.ts | 4 +- server/packets/PlayerDigging.ts | 4 +- server/packets/PlayerLook.ts | 4 +- server/packets/PlayerPosition.ts | 4 +- server/packets/PlayerPositionLook.ts | 4 +- server/packets/PreChunk.ts | 4 +- server/packets/Respawn.ts | 4 +- server/packets/SpawnPosition.ts | 4 +- server/packets/TimeUpdate.ts | 4 +- server/packets/UpdateHealth.ts | 4 +- server/packets/UseEntity.ts | 4 +- 40 files changed, 413 insertions(+), 68 deletions(-) create mode 100644 server/MetadataWriter.ts create mode 100644 server/enums/Animation.ts create mode 100644 server/enums/MetadataFieldType.ts rename server/enums/{Packets.ts => Packet.ts} (81%) create mode 100644 server/packets/Animation.ts create mode 100644 server/packets/BlockChange.ts create mode 100644 server/packets/EntityAction.ts create mode 100644 server/packets/EntityMetadata.ts diff --git a/server/MPClient.ts b/server/MPClient.ts index 5eb99a0..4b0f614 100644 --- a/server/MPClient.ts +++ b/server/MPClient.ts @@ -1,6 +1,6 @@ import { Socket } from "net"; import { Reader, Writer } from "../bufferStuff"; -import { Packets } from "./enums/Packets"; +import { Packet } from "./enums/Packet"; import { PacketPlayer } from "./packets/Player"; import { PacketPlayerPosition } from "./packets/PlayerPosition"; import { PacketPlayerLook } from "./packets/PlayerLook"; @@ -10,16 +10,25 @@ import { PacketChat } from "./packets/Chat"; import { MinecraftServer } from "./MinecraftServer"; import { Vec3 } from "./Vec3"; import { Console } from "../console"; +import { PacketPlayerDigging } from "./packets/PlayerDigging"; +import { PacketAnimation } from "./packets/Animation"; +import { PacketEntityAction } from "./packets/EntityAction"; +import { IPacket } from "./packets/IPacket"; +import { Animation } from "./enums/Animation"; export class MPClient { private readonly mcServer:MinecraftServer; private readonly socket:Socket; public readonly entity:Player; + private diggingAt:Vec3; + public constructor(mcServer:MinecraftServer, socket:Socket, entity:Player) { this.mcServer = mcServer; this.socket = socket; this.entity = entity; + + this.diggingAt = new Vec3(); } private mapCoordsToFace(pos:Vec3, face:number) { @@ -49,12 +58,18 @@ export class MPClient { const packetId = reader.readUByte(); switch (packetId) { - case Packets.Chat: this.handleChat(new PacketChat().readData(reader)); break; - case Packets.Player: this.handlePacketPlayer(new PacketPlayer().readData(reader)); break; - case Packets.PlayerPosition: this.handlePacketPlayerPosition(new PacketPlayerPosition().readData(reader)); break; - case Packets.PlayerLook: this.handlePacketPlayerLook(new PacketPlayerLook().readData(reader)); break; - case Packets.PlayerPositionLook: this.handlePacketPlayerPositionLook(new PacketPlayerPositionLook().readData(reader)); break; - case Packets.PlayerDigging: this.handlePacketPlayerDigging(); break; + case Packet.Chat: this.handleChat(new PacketChat().readData(reader)); break; + case Packet.Player: this.handlePacketPlayer(new PacketPlayer().readData(reader)); break; + case Packet.PlayerPosition: this.handlePacketPlayerPosition(new PacketPlayerPosition().readData(reader)); break; + case Packet.PlayerLook: this.handlePacketPlayerLook(new PacketPlayerLook().readData(reader)); break; + case Packet.PlayerPositionLook: this.handlePacketPlayerPositionLook(new PacketPlayerPositionLook().readData(reader)); break; + case Packet.PlayerDigging: this.handlePacketPlayerDigging(new PacketPlayerDigging().readData(reader)); break; + //case Packets.PlayerBlockPlacement: break; + //case Packets.HoldingChange: break; + //case Packets.UseBed: break; + case Packet.Animation: this.handlePacketAnimation(new PacketAnimation().readData(reader)); break; + case Packet.EntityAction: this.handlePacketEntityAction(new PacketEntityAction().readData(reader)); break; + default: Console.printWarn(`UNIMPLEMENTED PACKET: ${Packet[packetId]}`); break; } } @@ -106,8 +121,38 @@ export class MPClient { this.entity.pitch = packet.pitch; } - private handlePacketPlayerDigging() { + private handlePacketPlayerDigging(packet:PacketPlayerDigging) { + // Special drop item case + if (packet.status === 4) { + // TODO: Handle dropping items + return; + } + this.diggingAt.set(packet.x, packet.y, packet.z); + //this.mapCoordsToFace(this.diggingAt, packet.face); + + if (packet.status === 0) { + // Started digging + } else if (packet.status === 2) { + if (this.entity.world.getBlockId(this.diggingAt.x, this.diggingAt.y, this.diggingAt.z) != 0) { + this.entity.world.setBlock(0, this.diggingAt.x, this.diggingAt.y, this.diggingAt.z, true); + } + } + } + + // Animation start + private handlePacketAnimation(packet:PacketAnimation) { + // Forward this packet to all nearby clients + this.entity.world.sendToNearbyClients(this.entity, packet.writeData()); + } + + private handlePacketEntityAction(packet:PacketEntityAction) { + // Forward this packet to all nearby clients + switch (packet.action) { + case 1: this.entity.crouching = true; break; + case 2: this.entity.crouching = false; break; + case 3: break; // TODO: Leave Bed + } } public send(buffer:Buffer|Writer) { diff --git a/server/MetadataWriter.ts b/server/MetadataWriter.ts new file mode 100644 index 0000000..73c3515 --- /dev/null +++ b/server/MetadataWriter.ts @@ -0,0 +1,69 @@ +import { Writer } from "../bufferStuff"; +import { FunkyArray } from "../funkyArray"; +import { MetadataFieldType } from "./enums/MetadataFieldType"; + +export class MetadataEntry { + public type:MetadataFieldType; + public value:number|string; + + public constructor(type:MetadataFieldType, value:number|string) { + this.type = type; + this.value = value; + } +} + +export class MetadataWriter { + // https://wiki.vg/index.php?title=Protocol&oldid=488#Entity_Metadata_.280x28.29 + private entries:FunkyArray; // TODO: Extend with Item and Vector types + + public constructor() { + this.entries = new FunkyArray(); + } + + public addMetadataEntry(identifier:number, entry:MetadataEntry) { + this.entries.set(identifier, entry); + } + + private calculateBufferSize() { + let size = this.entries.length + 1; // Type/Identifiers + Stream end magic + this.entries.forEach(entry => { + switch (entry.type) { + case MetadataFieldType.Byte: size += 1; break; + case MetadataFieldType.Short: size += 2; break; + case MetadataFieldType.Int: size += 4; break; + case MetadataFieldType.Float: size += 4; break; + case MetadataFieldType.String: + if (typeof(entry.value) === "string") { + size += 2 + entry.value.length * 2; break; + } + } + }) + + return size; + } + + public writeBuffer() { + const writer = new Writer(this.calculateBufferSize()); + for (let key of this.entries.keys) { + const entry = this.entries.get(key); + if (entry instanceof MetadataEntry) { + writer.writeByte((entry.type << 5 | key & 0x1f) & 0xff); + if (typeof(entry.value) === "number") { + switch (entry.type) { + case MetadataFieldType.Byte: writer.writeByte(entry.value); break; + case MetadataFieldType.Short: writer.writeShort(entry.value); break; + case MetadataFieldType.Int: writer.writeInt(entry.value); break; + case MetadataFieldType.Float: writer.writeFloat(entry.value); break; + } + } else if (typeof(entry.value) === "string") { + writer.writeString(entry.value); + } + } + } + + // Metadata end magic + writer.writeByte(0x7F); + + return writer.toBuffer(); + } +} \ No newline at end of file diff --git a/server/MinecraftServer.ts b/server/MinecraftServer.ts index 04f262b..cfc716d 100644 --- a/server/MinecraftServer.ts +++ b/server/MinecraftServer.ts @@ -4,7 +4,7 @@ import { Server, Socket, SocketAddress } from "net"; import { FunkyArray } from "../funkyArray"; import { World } from "./World"; import { Reader } from "../bufferStuff"; -import { Packets } from "./enums/Packets"; +import { Packet } from "./enums/Packet"; import { PacketHandshake } from "./packets/Handshake"; import { MPClient } from "./MPClient"; import { PacketKeepAlive } from "./packets/KeepAlive"; @@ -58,13 +58,13 @@ export class MinecraftServer { // Generate spawn area (overworld) const generateStartTime = Date.now(); - Console.printInfo("[Overworld] Generating spawn area..."); + Console.printInfo("Generating spawn area..."); let generatedCount = 0; for (let x = -3; x < 3; x++) { for (let z = -3; z < 3; z++) { this.overworld.getChunk(x, z); if (generatedCount++ % 5 === 0) { - Console.printInfo(`[Overworld] Generating spawn area... ${Math.floor(generatedCount / 36 * 100)}%`); + Console.printInfo(`Generating spawn area... ${Math.floor(generatedCount / 36 * 100)}%`); } } } @@ -171,9 +171,9 @@ export class MinecraftServer { const packetId = reader.readUByte(); switch (packetId) { // TODO: Handle timeouts at some point, idk. - case Packets.KeepAlive: break; - case Packets.LoginRequest: this.handleLoginRequest(reader, socket, setMPClient.bind(this)); break; - case Packets.Handshake: this.handleHandshake(reader, socket); break; + case Packet.KeepAlive: break; + case Packet.LoginRequest: this.handleLoginRequest(reader, socket, setMPClient.bind(this)); break; + case Packet.Handshake: this.handleHandshake(reader, socket); break; } }); } diff --git a/server/Vec3.ts b/server/Vec3.ts index 7670f24..2fef13b 100644 --- a/server/Vec3.ts +++ b/server/Vec3.ts @@ -16,4 +16,10 @@ export class Vec3 { this.x = this.y = this.z = 0; } } + + public set(x:number, y:number, z:number) { + this.x = x; + this.y = y; + this.z = z; + } } \ No newline at end of file diff --git a/server/World.ts b/server/World.ts index 5775772..196f545 100644 --- a/server/World.ts +++ b/server/World.ts @@ -5,6 +5,7 @@ import { Player } from "./entities/Player"; //import { FlatGenerator } from "./generators/Flat"; import { HillyGenerator } from "./generators/Hilly"; import { IGenerator } from "./generators/IGenerator"; +import { PacketBlockChange } from "./packets/BlockChange"; export class World { public static ENTITY_MAX_SEND_DISTANCE = 50; @@ -61,6 +62,29 @@ export class World { return existingChunk; } + public getBlockId(x:number, y:number, z:number) { + const chunkX = x >> 4, + chunkZ = z >> 4; + + return this.getChunk(chunkX, chunkZ).getBlockId(x - chunkX << 4, y, z - chunkZ << 4); + } + + public setBlock(blockId:number, x:number, y:number, z:number, doBlockUpdate?:boolean) { + const chunkX = x >> 4, + chunkZ = z >> 4; + + const chunk = this.getChunk(chunkX, chunkZ); + chunk.setBlock(blockId, x - chunkX << 4, y, z - chunkZ << 4); + + const blockUpdatePacket = new PacketBlockChange(x, y, z, blockId, 0).writeData(); // TODO: Handle metadata + if (doBlockUpdate) { + // Send block update to all players that have this chunk loaded + chunk.playersInChunk.forEach(player => { + player.mpClient?.send(blockUpdatePacket); + }); + } + } + public sendToNearbyClients(sentFrom:IEntity, buffer:Buffer) { this.players.forEach(player => { if (sentFrom.entityId !== player.entityId && Math.abs(sentFrom.distanceTo(player)) < World.ENTITY_MAX_SEND_DISTANCE) { diff --git a/server/entities/Entity.ts b/server/entities/Entity.ts index 5319197..56ae40b 100644 --- a/server/entities/Entity.ts +++ b/server/entities/Entity.ts @@ -1,4 +1,7 @@ +import { MetadataEntry, MetadataWriter } from "../MetadataWriter"; import { World } from "../World"; +import { MetadataFieldType } from "../enums/MetadataFieldType"; +import { PacketEntityMetadata } from "../packets/EntityMetadata"; import { IEntity } from "./IEntity"; export class Entity implements IEntity { @@ -14,11 +17,41 @@ export class Entity implements IEntity { public lastY:number; public lastZ:number; + public fire:number; + + public crouching:boolean; + private lastCrouchState:boolean; + private lastFireState:boolean; + public constructor(world:World) { this.entityId = Entity.nextEntityId++; + this.fire = 0; + this.world = world; this.x = this.y = this.z = this.lastX = this.lastY = this.lastZ = 0; + this.crouching = this.lastCrouchState = this.lastFireState = false; + } + + updateMetadata() { + const crouchStateChanged = this.crouching !== this.lastCrouchState; + const fireStateChanged = this.fire > 0 !== this.lastFireState; + if (crouchStateChanged || fireStateChanged) { + const metadata = new MetadataWriter(); + // Flags: + // 1 = On Fire + // 2 = Player crouched + // 4 = Player on mount? + //metadata.addMetadataEntry(0, new MetadataEntry(MetadataFieldType.Byte, 1)); + if (crouchStateChanged) { + metadata.addMetadataEntry(0, new MetadataEntry(MetadataFieldType.Byte, Number(this.fire > 0) + Number(this.crouching) * 2)); + } + + this.world.sendToNearbyClients(this, new PacketEntityMetadata(this.entityId, metadata.writeBuffer()).writeData()); + + this.lastCrouchState = this.crouching; + this.lastFireState = this.fire > 0; + } } distanceTo(entity:IEntity) { @@ -30,6 +63,16 @@ export class Entity implements IEntity { } onTick() { + this.updateMetadata(); + + if (this.fire > 0) { + if (this.fire % 20 === 0) { + + } + + this.fire--; + } + this.lastX = this.x; this.lastY = this.y; this.lastZ = this.z; diff --git a/server/entities/EntityLiving.ts b/server/entities/EntityLiving.ts index 60dc051..125e83f 100644 --- a/server/entities/EntityLiving.ts +++ b/server/entities/EntityLiving.ts @@ -47,8 +47,8 @@ export class EntityLiving extends Entity { const diffYaw = this.absYaw - this.lastAbsYaw; const diffPitch = this.absPitch - this.lastAbsPitch; - const doRelativeMove = Math.abs(diffX) >= 5 || Math.abs(diffY) >= 5 || Math.abs(diffZ) >= 5; - const doLook = Math.abs(diffYaw) >= 5 || Math.abs(diffPitch) >= 5; + const doRelativeMove = Math.abs(diffX) >= 4 || Math.abs(diffY) >= 4 || Math.abs(diffZ) >= 4; + const doLook = Math.abs(diffYaw) >= 4 || Math.abs(diffPitch) >= 4; if (Math.abs(diffX) > 128 || Math.abs(diffY) > 128 || Math.abs(diffZ) > 128) { this.world.sendToNearbyClients(this, new PacketEntityTeleport(this.entityId, this.absX, this.absY, this.absZ, this.absYaw, this.absPitch).writeData()); } else if (doRelativeMove && doLook) { diff --git a/server/entities/IEntity.ts b/server/entities/IEntity.ts index 722ca48..832a069 100644 --- a/server/entities/IEntity.ts +++ b/server/entities/IEntity.ts @@ -6,6 +6,8 @@ export interface IEntity { lastX:number, lastY:number, lastZ:number, + crouching:boolean, + updateMetadata:() => void, distanceTo:(entity:IEntity) => number, onTick:() => void } \ No newline at end of file diff --git a/server/enums/Animation.ts b/server/enums/Animation.ts new file mode 100644 index 0000000..8fe5ff5 --- /dev/null +++ b/server/enums/Animation.ts @@ -0,0 +1,9 @@ +export enum Animation { + None = 0, + SwingArm = 1, + Damage = 2, + LeaveBed = 3, + Unknown102 = 102, + Crouch = 104, + Uncrouch = 105, +} \ No newline at end of file diff --git a/server/enums/MetadataFieldType.ts b/server/enums/MetadataFieldType.ts new file mode 100644 index 0000000..ff8d434 --- /dev/null +++ b/server/enums/MetadataFieldType.ts @@ -0,0 +1,9 @@ +export enum MetadataFieldType { + Byte = 0, + Short = 1, + Int = 2, + Float = 3, + String = 4, + Item = 5, + Vector = 6 +} \ No newline at end of file diff --git a/server/enums/Packets.ts b/server/enums/Packet.ts similarity index 81% rename from server/enums/Packets.ts rename to server/enums/Packet.ts index ffaba34..88e6b11 100644 --- a/server/enums/Packets.ts +++ b/server/enums/Packet.ts @@ -1,4 +1,5 @@ -export enum Packets { +// https://wiki.vg/index.php?title=Protocol&oldid=488 +export enum Packet { KeepAlive = 0x00, LoginRequest = 0x01, Handshake = 0x02, @@ -20,9 +21,13 @@ export enum Packets { Animation = 0x12, EntityAction = 0x13, NamedEntitySpawn = 0x14, + + EntityMetadata = 0x28, PreChunk = 0x32, MapChunk = 0x33, + MultiBlockChange = 0x34, + BlockChange = 0x035, Entity = 0x1E, EntityRelativeMove = 0x1F, diff --git a/server/packets/Animation.ts b/server/packets/Animation.ts new file mode 100644 index 0000000..b57401e --- /dev/null +++ b/server/packets/Animation.ts @@ -0,0 +1,30 @@ +import { Reader, Writer } from "../../bufferStuff"; +import { Packet } from "../enums/Packet"; +import { IPacket } from "./IPacket"; + +export class PacketAnimation implements IPacket { + public packetId = Packet.Animation; + public entityId:number; + public animation:number; + + public constructor(entityId?:number, animation?:number) { + if (typeof(entityId) == "number" && typeof(animation) === "number") { + this.entityId = entityId; + this.animation = animation; + } else { + this.entityId = Number.MIN_VALUE; + this.animation = Number.MIN_VALUE; + } + } + + public readData(reader:Reader) { + this.entityId = reader.readInt(); + this.animation = reader.readByte(); + + return this; + } + + public writeData() { + return new Writer(6).writeUByte(this.packetId).writeInt(this.entityId).writeByte(this.animation).toBuffer(); + } +} \ No newline at end of file diff --git a/server/packets/BlockChange.ts b/server/packets/BlockChange.ts new file mode 100644 index 0000000..3855e65 --- /dev/null +++ b/server/packets/BlockChange.ts @@ -0,0 +1,42 @@ +import { Reader, Writer } from "../../bufferStuff"; +import { Packet } from "../enums/Packet"; +import { IPacket } from "./IPacket"; + +export class PacketBlockChange implements IPacket { + public packetId = Packet.BlockChange; + public x:number; + public y:number; + public z:number; + public blockType:number; + public blockMetadata:number; + + public constructor(x?:number, y?:number, z?:number, blockType?:number, blockMetadata?:number) { + if (typeof(x) == "number" && typeof(y) === "number" && typeof(z) === "number" && typeof(blockType) === "number" && typeof(blockMetadata) === "number") { + this.x = x; + this.y = y; + this.z = z; + this.blockType = blockType; + this.blockMetadata = blockMetadata; + } else { + this.x = Number.MIN_VALUE; + this.y = Number.MIN_VALUE; + this.z = Number.MIN_VALUE; + this.blockType = Number.MIN_VALUE; + this.blockMetadata = Number.MIN_VALUE; + } + } + + public readData(reader:Reader) { + this.x = reader.readInt(); + this.y = reader.readByte(); + this.z = reader.readInt(); + this.blockType = reader.readByte(); + this.blockMetadata = reader.readByte(); + + return this; + } + + public writeData() { + return new Writer(12).writeUByte(this.packetId).writeInt(this.x).writeByte(this.y).writeInt(this.z).writeByte(this.blockType).writeByte(this.blockMetadata).toBuffer(); + } +} \ No newline at end of file diff --git a/server/packets/Chat.ts b/server/packets/Chat.ts index 5c7344d..2de7e2d 100644 --- a/server/packets/Chat.ts +++ b/server/packets/Chat.ts @@ -1,9 +1,9 @@ import { Reader, Writer } from "../../bufferStuff"; -import { Packets } from "../enums/Packets"; +import { Packet } from "../enums/Packet"; import { IPacket } from "./IPacket"; export class PacketChat implements IPacket { - public packetId = Packets.Chat; + public packetId = Packet.Chat; public message:string; public constructor(message?:string) { diff --git a/server/packets/DisconnectKick.ts b/server/packets/DisconnectKick.ts index 3779cf1..98b5004 100644 --- a/server/packets/DisconnectKick.ts +++ b/server/packets/DisconnectKick.ts @@ -1,9 +1,9 @@ import { Reader, Writer } from "../../bufferStuff"; -import { Packets } from "../enums/Packets"; +import { Packet } from "../enums/Packet"; import { IPacket } from "./IPacket"; export class PacketDisconnectKick implements IPacket { - public packetId = Packets.DisconnectKick; + public packetId = Packet.DisconnectKick; public reason:string; public constructor(reason?:string) { diff --git a/server/packets/Entity.ts b/server/packets/Entity.ts index 86d7f7d..527e0fb 100644 --- a/server/packets/Entity.ts +++ b/server/packets/Entity.ts @@ -1,9 +1,9 @@ import { Reader, Writer } from "../../bufferStuff"; -import { Packets } from "../enums/Packets"; +import { Packet } from "../enums/Packet"; import { IPacket } from "./IPacket"; export class PacketEntity implements IPacket { - public packetId = Packets.Entity; + public packetId = Packet.Entity; public entityId:number; public constructor(entityId?:number) { diff --git a/server/packets/EntityAction.ts b/server/packets/EntityAction.ts new file mode 100644 index 0000000..8bf5c3c --- /dev/null +++ b/server/packets/EntityAction.ts @@ -0,0 +1,30 @@ +import { Reader, Writer } from "../../bufferStuff"; +import { Packet } from "../enums/Packet"; +import { IPacket } from "./IPacket"; + +export class PacketEntityAction implements IPacket { + public packetId = Packet.EntityAction; + public entityId:number; + public action:number; + + public constructor(entityId?:number, action?:number) { + if (typeof(entityId) == "number" && typeof(action) === "number") { + this.entityId = entityId; + this.action = action; + } else { + this.entityId = Number.MIN_VALUE; + this.action = Number.MIN_VALUE; + } + } + + public readData(reader:Reader) { + this.entityId = reader.readInt(); + this.action = reader.readByte(); + + return this; + } + + public writeData() { + return new Writer(6).writeUByte(this.packetId).writeInt(this.entityId).writeByte(this.action).toBuffer(); + } +} \ No newline at end of file diff --git a/server/packets/EntityEquipment.ts b/server/packets/EntityEquipment.ts index b4c1440..b4c9cd9 100644 --- a/server/packets/EntityEquipment.ts +++ b/server/packets/EntityEquipment.ts @@ -1,9 +1,9 @@ import { Reader, Writer } from "../../bufferStuff"; -import { Packets } from "../enums/Packets"; +import { Packet } from "../enums/Packet"; import { IPacket } from "./IPacket"; export class PacketEntityEquipment implements IPacket { - public packetId = Packets.EntityEquipment; + public packetId = Packet.EntityEquipment; public entityId:number; public slot:number; public itemId:number; diff --git a/server/packets/EntityLook.ts b/server/packets/EntityLook.ts index 90b5e3e..c9ea0c6 100644 --- a/server/packets/EntityLook.ts +++ b/server/packets/EntityLook.ts @@ -1,9 +1,9 @@ import { Reader, Writer } from "../../bufferStuff"; -import { Packets } from "../enums/Packets"; +import { Packet } from "../enums/Packet"; import { IPacket } from "./IPacket"; export class PacketEntityLook implements IPacket { - public packetId = Packets.EntityLook; + public packetId = Packet.EntityLook; public entityId:number; public yaw:number; public pitch:number; diff --git a/server/packets/EntityLookRelativeMove.ts b/server/packets/EntityLookRelativeMove.ts index b868900..a8d9190 100644 --- a/server/packets/EntityLookRelativeMove.ts +++ b/server/packets/EntityLookRelativeMove.ts @@ -1,9 +1,9 @@ import { Reader, Writer } from "../../bufferStuff"; -import { Packets } from "../enums/Packets"; +import { Packet } from "../enums/Packet"; import { IPacket } from "./IPacket"; export class PacketEntityLookRelativeMove implements IPacket { - public packetId = Packets.EntityLookRelativeMove; + public packetId = Packet.EntityLookRelativeMove; public entityId:number; public dX:number; public dY:number; diff --git a/server/packets/EntityMetadata.ts b/server/packets/EntityMetadata.ts new file mode 100644 index 0000000..a215991 --- /dev/null +++ b/server/packets/EntityMetadata.ts @@ -0,0 +1,31 @@ +import { Reader, Writer } from "../../bufferStuff"; +import { Packet } from "../enums/Packet"; +import { IPacket } from "./IPacket"; + +const EMPTY_BUFFER = Buffer.alloc(0); + +export class PacketEntityMetadata implements IPacket { + public packetId = Packet.EntityMetadata; + public entityId:number; + public metadata:Buffer; + + public constructor(entityId?:number, metadata?:Buffer) { + if (typeof(entityId) == "number" && metadata instanceof Buffer) { + this.entityId = entityId; + this.metadata = metadata; + } else { + this.entityId = Number.MIN_VALUE; + this.metadata = EMPTY_BUFFER; + } + } + + public readData(reader:Reader) { + // TODO: EntityMetadata reading + + return this; + } + + public writeData() { + return new Writer(5).writeUByte(this.packetId).writeInt(this.entityId).writeBuffer(this.metadata).toBuffer(); + } +} \ No newline at end of file diff --git a/server/packets/EntityRelativeMove.ts b/server/packets/EntityRelativeMove.ts index cc99eb9..3aac6c5 100644 --- a/server/packets/EntityRelativeMove.ts +++ b/server/packets/EntityRelativeMove.ts @@ -1,9 +1,9 @@ import { Reader, Writer } from "../../bufferStuff"; -import { Packets } from "../enums/Packets"; +import { Packet } from "../enums/Packet"; import { IPacket } from "./IPacket"; export class PacketEntityRelativeMove implements IPacket { - public packetId = Packets.EntityRelativeMove; + public packetId = Packet.EntityRelativeMove; public entityId:number; public dX:number; public dY:number; diff --git a/server/packets/EntityTeleport.ts b/server/packets/EntityTeleport.ts index e1f9c8a..8c28dd4 100644 --- a/server/packets/EntityTeleport.ts +++ b/server/packets/EntityTeleport.ts @@ -1,9 +1,9 @@ import { Reader, Writer } from "../../bufferStuff"; -import { Packets } from "../enums/Packets"; +import { Packet } from "../enums/Packet"; import { IPacket } from "./IPacket"; export class PacketEntityTeleport implements IPacket { - public packetId = Packets.EntityTeleport; + public packetId = Packet.EntityTeleport; public entityId:number; public x:number; public y:number; diff --git a/server/packets/Handshake.ts b/server/packets/Handshake.ts index f38c107..3de41bc 100644 --- a/server/packets/Handshake.ts +++ b/server/packets/Handshake.ts @@ -1,9 +1,9 @@ import { Reader, Writer } from "../../bufferStuff"; -import { Packets } from "../enums/Packets"; +import { Packet } from "../enums/Packet"; import { IPacket } from "./IPacket"; export class PacketHandshake implements IPacket { - public packetId:Packets = Packets.Handshake; + public packetId:Packet = Packet.Handshake; private username:string; public constructor(username?:string) { diff --git a/server/packets/IPacket.ts b/server/packets/IPacket.ts index 6447e48..d9da384 100644 --- a/server/packets/IPacket.ts +++ b/server/packets/IPacket.ts @@ -1,8 +1,8 @@ import { Reader } from "../../bufferStuff"; -import { Packets } from "../enums/Packets"; +import { Packet } from "../enums/Packet"; export interface IPacket { - packetId: Packets, + packetId: Packet, readData: (reader:Reader) => IPacket, writeData: () => Buffer|Promise } \ No newline at end of file diff --git a/server/packets/KeepAlive.ts b/server/packets/KeepAlive.ts index 0462d66..dbd2c9d 100644 --- a/server/packets/KeepAlive.ts +++ b/server/packets/KeepAlive.ts @@ -1,10 +1,10 @@ import { Reader, Writer } from "../../bufferStuff"; -import { Packets } from "../enums/Packets"; +import { Packet } from "../enums/Packet"; import { IPacket } from "./IPacket"; export class PacketKeepAlive implements IPacket { - public packetId = Packets.KeepAlive; - private static readonly KeepAliveBuffer:Buffer = new Writer(1).writeByte(Packets.KeepAlive).toBuffer(); + public packetId = Packet.KeepAlive; + private static readonly KeepAliveBuffer:Buffer = new Writer(1).writeByte(Packet.KeepAlive).toBuffer(); public readData(reader:Reader) { reader; diff --git a/server/packets/LoginRequest.ts b/server/packets/LoginRequest.ts index 01c6405..52afe67 100644 --- a/server/packets/LoginRequest.ts +++ b/server/packets/LoginRequest.ts @@ -1,9 +1,9 @@ import { Reader, Writer } from "../../bufferStuff"; -import { Packets } from "../enums/Packets"; +import { Packet } from "../enums/Packet"; import { IPacket } from "./IPacket"; export class PacketLoginRequest implements IPacket { - public packetId = Packets.LoginRequest; + public packetId = Packet.LoginRequest; public protocolVersion:number; public username:string; public mapSeed:number; diff --git a/server/packets/MapChunk.ts b/server/packets/MapChunk.ts index 9880ba0..45dcf5a 100644 --- a/server/packets/MapChunk.ts +++ b/server/packets/MapChunk.ts @@ -1,11 +1,11 @@ import { deflate } from "zlib"; import { Reader, Writer } from "../../bufferStuff"; -import { Packets } from "../enums/Packets"; +import { Packet } from "../enums/Packet"; import { IPacket } from "./IPacket"; import { Chunk } from "../Chunk"; export class PacketMapChunk implements IPacket { - public packetId = Packets.MapChunk; + public packetId = Packet.MapChunk; public x:number; public y:number; public z:number; diff --git a/server/packets/NamedEntitySpawn.ts b/server/packets/NamedEntitySpawn.ts index 07498b9..1ee4abb 100644 --- a/server/packets/NamedEntitySpawn.ts +++ b/server/packets/NamedEntitySpawn.ts @@ -1,9 +1,9 @@ import { Reader, Writer } from "../../bufferStuff"; -import { Packets } from "../enums/Packets"; +import { Packet } from "../enums/Packet"; import { IPacket } from "./IPacket"; export class PacketNamedEntitySpawn implements IPacket { - public packetId = Packets.NamedEntitySpawn; + public packetId = Packet.NamedEntitySpawn; public entityId:number; public playerName:string; public x:number; diff --git a/server/packets/Player.ts b/server/packets/Player.ts index a2aa928..8d877bc 100644 --- a/server/packets/Player.ts +++ b/server/packets/Player.ts @@ -1,9 +1,9 @@ import { Reader, Writer } from "../../bufferStuff"; -import { Packets } from "../enums/Packets"; +import { Packet } from "../enums/Packet"; import { IPacket } from "./IPacket"; export class PacketPlayer implements IPacket { - public packetId = Packets.Player; + public packetId = Packet.Player; public onGround:boolean; public constructor(onGround?:boolean) { diff --git a/server/packets/PlayerDigging.ts b/server/packets/PlayerDigging.ts index fc852ba..85c6da7 100644 --- a/server/packets/PlayerDigging.ts +++ b/server/packets/PlayerDigging.ts @@ -1,9 +1,9 @@ import { Reader, Writer } from "../../bufferStuff"; -import { Packets } from "../enums/Packets"; +import { Packet } from "../enums/Packet"; import { IPacket } from "./IPacket"; export class PacketPlayerDigging implements IPacket { - public packetId = Packets.PlayerDigging; + public packetId = Packet.PlayerDigging; public status:number; public x:number; public y:number; diff --git a/server/packets/PlayerLook.ts b/server/packets/PlayerLook.ts index 9577991..bab77b7 100644 --- a/server/packets/PlayerLook.ts +++ b/server/packets/PlayerLook.ts @@ -1,9 +1,9 @@ import { Reader, Writer } from "../../bufferStuff"; -import { Packets } from "../enums/Packets"; +import { Packet } from "../enums/Packet"; import { IPacket } from "./IPacket"; export class PacketPlayerLook implements IPacket { - public packetId = Packets.Player; + public packetId = Packet.Player; public yaw:number; public pitch:number; public onGround:boolean; diff --git a/server/packets/PlayerPosition.ts b/server/packets/PlayerPosition.ts index d83f099..ae1a9e1 100644 --- a/server/packets/PlayerPosition.ts +++ b/server/packets/PlayerPosition.ts @@ -1,9 +1,9 @@ import { Reader, Writer } from "../../bufferStuff"; -import { Packets } from "../enums/Packets"; +import { Packet } from "../enums/Packet"; import { IPacket } from "./IPacket"; export class PacketPlayerPosition implements IPacket { - public packetId = Packets.PlayerPosition; + public packetId = Packet.PlayerPosition; public x:number; public y:number; public stance:number; diff --git a/server/packets/PlayerPositionLook.ts b/server/packets/PlayerPositionLook.ts index 4f9aae5..7119e9b 100644 --- a/server/packets/PlayerPositionLook.ts +++ b/server/packets/PlayerPositionLook.ts @@ -1,9 +1,9 @@ import { Reader, Writer } from "../../bufferStuff"; -import { Packets } from "../enums/Packets"; +import { Packet } from "../enums/Packet"; import { IPacket } from "./IPacket"; export class PacketPlayerPositionLook implements IPacket { - public packetId = Packets.PlayerPosition; + public packetId = Packet.PlayerPosition; public x:number; public y:number; public stance:number; diff --git a/server/packets/PreChunk.ts b/server/packets/PreChunk.ts index 38fde2d..679cae5 100644 --- a/server/packets/PreChunk.ts +++ b/server/packets/PreChunk.ts @@ -1,9 +1,9 @@ import { Reader, Writer } from "../../bufferStuff"; -import { Packets } from "../enums/Packets"; +import { Packet } from "../enums/Packet"; import { IPacket } from "./IPacket"; export class PacketPreChunk implements IPacket { - public packetId = Packets.PreChunk; + public packetId = Packet.PreChunk; public x:number; public z:number; public mode:boolean; diff --git a/server/packets/Respawn.ts b/server/packets/Respawn.ts index cd08787..93367b8 100644 --- a/server/packets/Respawn.ts +++ b/server/packets/Respawn.ts @@ -1,9 +1,9 @@ import { Reader, Writer } from "../../bufferStuff"; -import { Packets } from "../enums/Packets"; +import { Packet } from "../enums/Packet"; import { IPacket } from "./IPacket"; export class PacketRespawn implements IPacket { - public packetId = Packets.Respawn; + public packetId = Packet.Respawn; public health:number; public constructor(health:number) { diff --git a/server/packets/SpawnPosition.ts b/server/packets/SpawnPosition.ts index e530093..dccac3a 100644 --- a/server/packets/SpawnPosition.ts +++ b/server/packets/SpawnPosition.ts @@ -1,9 +1,9 @@ import { Reader, Writer } from "../../bufferStuff"; -import { Packets } from "../enums/Packets"; +import { Packet } from "../enums/Packet"; import { IPacket } from "./IPacket"; export class PacketSpawnPosition implements IPacket { - public packetId = Packets.SpawnPosition; + public packetId = Packet.SpawnPosition; public x:number; public y:number; public z:number; diff --git a/server/packets/TimeUpdate.ts b/server/packets/TimeUpdate.ts index c361dba..06b3334 100644 --- a/server/packets/TimeUpdate.ts +++ b/server/packets/TimeUpdate.ts @@ -1,9 +1,9 @@ import { Reader, Writer } from "../../bufferStuff"; -import { Packets } from "../enums/Packets"; +import { Packet } from "../enums/Packet"; import { IPacket } from "./IPacket"; export class PacketTimeUpdate implements IPacket { - public packetId = Packets.TimeUpdate; + public packetId = Packet.TimeUpdate; public time:bigint; public constructor(time:bigint) { diff --git a/server/packets/UpdateHealth.ts b/server/packets/UpdateHealth.ts index 015c155..8658cc1 100644 --- a/server/packets/UpdateHealth.ts +++ b/server/packets/UpdateHealth.ts @@ -1,9 +1,9 @@ import { Reader, Writer } from "../../bufferStuff"; -import { Packets } from "../enums/Packets"; +import { Packet } from "../enums/Packet"; import { IPacket } from "./IPacket"; export class PacketUpdateHealth implements IPacket { - public packetId = Packets.UpdateHealth; + public packetId = Packet.UpdateHealth; public health:number; public constructor(health:number) { diff --git a/server/packets/UseEntity.ts b/server/packets/UseEntity.ts index c6515a6..37a9f0c 100644 --- a/server/packets/UseEntity.ts +++ b/server/packets/UseEntity.ts @@ -1,9 +1,9 @@ import { Reader, Writer } from "../../bufferStuff"; -import { Packets } from "../enums/Packets"; +import { Packet } from "../enums/Packet"; import { IPacket } from "./IPacket"; export class PacketUseEntity implements IPacket { - public packetId = Packets.UseEntity; + public packetId = Packet.UseEntity; public userId:number; public targetId:number; public leftClick:boolean;