Animations & Metadata
This commit is contained in:
parent
f93bb2605d
commit
b371521fda
40 changed files with 413 additions and 68 deletions
|
@ -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) {
|
||||
|
|
69
server/MetadataWriter.ts
Normal file
69
server/MetadataWriter.ts
Normal file
|
@ -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<number, MetadataEntry>; // TODO: Extend with Item and Vector types
|
||||
|
||||
public constructor() {
|
||||
this.entries = new FunkyArray<number, MetadataEntry>();
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -6,6 +6,8 @@ export interface IEntity {
|
|||
lastX:number,
|
||||
lastY:number,
|
||||
lastZ:number,
|
||||
crouching:boolean,
|
||||
updateMetadata:() => void,
|
||||
distanceTo:(entity:IEntity) => number,
|
||||
onTick:() => void
|
||||
}
|
9
server/enums/Animation.ts
Normal file
9
server/enums/Animation.ts
Normal file
|
@ -0,0 +1,9 @@
|
|||
export enum Animation {
|
||||
None = 0,
|
||||
SwingArm = 1,
|
||||
Damage = 2,
|
||||
LeaveBed = 3,
|
||||
Unknown102 = 102,
|
||||
Crouch = 104,
|
||||
Uncrouch = 105,
|
||||
}
|
9
server/enums/MetadataFieldType.ts
Normal file
9
server/enums/MetadataFieldType.ts
Normal file
|
@ -0,0 +1,9 @@
|
|||
export enum MetadataFieldType {
|
||||
Byte = 0,
|
||||
Short = 1,
|
||||
Int = 2,
|
||||
Float = 3,
|
||||
String = 4,
|
||||
Item = 5,
|
||||
Vector = 6
|
||||
}
|
|
@ -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,
|
30
server/packets/Animation.ts
Normal file
30
server/packets/Animation.ts
Normal file
|
@ -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();
|
||||
}
|
||||
}
|
42
server/packets/BlockChange.ts
Normal file
42
server/packets/BlockChange.ts
Normal file
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
30
server/packets/EntityAction.ts
Normal file
30
server/packets/EntityAction.ts
Normal file
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
31
server/packets/EntityMetadata.ts
Normal file
31
server/packets/EntityMetadata.ts
Normal file
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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<Buffer>
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue