implement player spawning, movement, animation, metadata and destroying, implement NBT serialization, version 1.1.7
This commit is contained in:
@@ -35,6 +35,7 @@ Click [here](https://labystudio.de/page/minecraft/) for a demo!
|
||||
- World
|
||||
- 16x16x16 Chunks
|
||||
- Block type, data, sky & block lightning
|
||||
- Entities
|
||||
- Minecraft Alpha Generator
|
||||
- 64 bits seed
|
||||
- Perlin terrain generation
|
||||
@@ -73,12 +74,14 @@ Click [here](https://labystudio.de/page/minecraft/) for a demo!
|
||||
- Hot-Bar
|
||||
- Chat
|
||||
- Debug
|
||||
- Player list
|
||||
- Multiplayer
|
||||
- Networking
|
||||
- RSA Encryption
|
||||
- AES Encryption
|
||||
- Compression
|
||||
- Splitting
|
||||
- NBT Serialization
|
||||
- Sub-Protocols
|
||||
- Handshake
|
||||
- Status
|
||||
@@ -89,6 +92,7 @@ Click [here](https://labystudio.de/page/minecraft/) for a demo!
|
||||
- Movement Packets
|
||||
- Block Update Packets
|
||||
- Chat Packets
|
||||
- Player Packets
|
||||
- Commands
|
||||
- /help
|
||||
- /time
|
||||
|
||||
@@ -26,7 +26,7 @@ import PlayerControllerMultiplayer from "./network/controller/PlayerControllerMu
|
||||
|
||||
export default class Minecraft {
|
||||
|
||||
static VERSION = "1.1.6"
|
||||
static VERSION = "1.1.7"
|
||||
static URL_GITHUB = "https://github.com/labystudio/js-minecraft";
|
||||
static PROTOCOL_VERSION = 47; //758;
|
||||
|
||||
@@ -124,6 +124,7 @@ export default class Minecraft {
|
||||
|
||||
if (this.world !== null) {
|
||||
this.world.getChunkProvider().getChunks().clear();
|
||||
this.world.clearEntities();
|
||||
this.world = null;
|
||||
this.player = null;
|
||||
this.loadingScreen = null;
|
||||
@@ -135,6 +136,14 @@ export default class Minecraft {
|
||||
this.loadingScreen.setTitle("Building terrain...");
|
||||
this.displayScreen(this.loadingScreen);
|
||||
|
||||
// Clear previous world
|
||||
if (this.world !== null) {
|
||||
this.world.getChunkProvider().getChunks().clear();
|
||||
this.world.clearEntities();
|
||||
this.worldRenderer.reset();
|
||||
this.itemRenderer.reset();
|
||||
}
|
||||
|
||||
// Create world
|
||||
this.world = world;
|
||||
this.worldRenderer.scene.add(this.world.group);
|
||||
@@ -277,9 +286,6 @@ export default class Minecraft {
|
||||
// Tick renderer
|
||||
this.worldRenderer.onTick();
|
||||
|
||||
// Tick the player
|
||||
this.player.onUpdate();
|
||||
|
||||
// Tick particle renderer
|
||||
this.particleRenderer.onTick();
|
||||
}
|
||||
|
||||
@@ -4,9 +4,11 @@ import Random from "../../util/Random.js";
|
||||
|
||||
export default class Entity {
|
||||
|
||||
constructor(minecraft, world) {
|
||||
constructor(minecraft, world, id) {
|
||||
this.minecraft = minecraft;
|
||||
this.world = world;
|
||||
this.id = id;
|
||||
|
||||
this.random = new Random();
|
||||
this.renderer = null;
|
||||
|
||||
@@ -24,7 +26,6 @@ export default class Entity {
|
||||
this.stepHeight = 0.0;
|
||||
|
||||
this.onGround = false;
|
||||
this.sneaking = false;
|
||||
|
||||
this.rotationYaw = 0;
|
||||
this.rotationPitch = 0;
|
||||
@@ -43,6 +44,12 @@ export default class Entity {
|
||||
this.ticksExisted = 0;
|
||||
this.isDead = false;
|
||||
|
||||
this.serverPositionX = 0;
|
||||
this.serverPositionY = 0;
|
||||
this.serverPositionZ = 0;
|
||||
|
||||
this.metaData = {};
|
||||
|
||||
this.boundingBox = new BoundingBox();
|
||||
this.setPosition(this.x, this.y, this.z);
|
||||
}
|
||||
@@ -70,19 +77,36 @@ export default class Entity {
|
||||
y + this.height,
|
||||
z + width
|
||||
);
|
||||
|
||||
this.motionX = 0;
|
||||
this.motionY = 0;
|
||||
this.motionZ = 0;
|
||||
|
||||
this.prevX = this.x;
|
||||
this.prevY = this.y;
|
||||
this.prevZ = this.z;
|
||||
}
|
||||
|
||||
setRotation(yaw, pitch) {
|
||||
this.rotationYaw = yaw;
|
||||
this.rotationPitch = pitch;
|
||||
this.rotationYaw = yaw % 360;
|
||||
this.rotationPitch = pitch % 360;
|
||||
}
|
||||
|
||||
setTargetPositionAndRotation(x, y, z, yaw, pitch, increments) {
|
||||
this.setPosition(x, y, z);
|
||||
this.setRotation(yaw, pitch);
|
||||
}
|
||||
|
||||
setPositionAndRotation(x, y, z, yaw, pitch) {
|
||||
this.prevX = this.x = x;
|
||||
this.prevY = this.y = y;
|
||||
this.prevZ = this.z = z;
|
||||
|
||||
this.prevRotationYaw = this.rotationYaw = yaw;
|
||||
this.prevRotationPitch = this.rotationPitch = pitch;
|
||||
|
||||
let diffYaw = (this.prevRotationYaw - yaw);
|
||||
if (diffYaw < -180) {
|
||||
this.prevRotationYaw += 360;
|
||||
}
|
||||
if (diffYaw >= 180) {
|
||||
this.prevRotationYaw -= 360;
|
||||
}
|
||||
|
||||
this.setPosition(this.x, this.y, this.z);
|
||||
this.setRotation(yaw, pitch);
|
||||
}
|
||||
|
||||
onUpdate() {
|
||||
@@ -119,7 +143,7 @@ export default class Entity {
|
||||
let originalTargetY = targetY;
|
||||
let originalTargetZ = targetZ;
|
||||
|
||||
if (this.onGround && this.sneaking) {
|
||||
if (this.onGround && this.isSneaking()) {
|
||||
for (; targetX !== 0.0 && this.world.getCollisionBoxes(this.boundingBox.offset(targetX, -this.stepHeight, 0.0)).length === 0; originalTargetX = targetX) {
|
||||
if (targetX < 0.05 && targetX >= -0.05) {
|
||||
targetX = 0.0;
|
||||
@@ -214,4 +238,34 @@ export default class Entity {
|
||||
|| this.rotationPitch !== this.prevRotationPitch;
|
||||
}
|
||||
|
||||
isSneaking() {
|
||||
return this.getFlag(1);
|
||||
}
|
||||
|
||||
setSneaking(sneaking) {
|
||||
this.setFlag(1, sneaking);
|
||||
}
|
||||
|
||||
updateMetaData(metaData) {
|
||||
for (const [id, value] of Object.entries(metaData)) {
|
||||
this.metaData[value.id] = value;
|
||||
}
|
||||
}
|
||||
|
||||
getFlag(flag) {
|
||||
return typeof this.metaData[0] !== "undefined" && (this.metaData[0].value & 1 << flag) !== 0;
|
||||
}
|
||||
|
||||
setFlag(flag, value) {
|
||||
if (typeof this.metaData[0] === "undefined") {
|
||||
this.metaData[0] = {id: 0, type: 0, value: 0};
|
||||
}
|
||||
|
||||
if (value) {
|
||||
this.metaData[0].value |= 1 << flag;
|
||||
} else {
|
||||
this.metaData[0].value &= ~(1 << flag);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -3,8 +3,8 @@ import MathHelper from "../../util/MathHelper.js";
|
||||
|
||||
export default class EntityLiving extends Entity {
|
||||
|
||||
constructor(minecraft, world) {
|
||||
super(minecraft, world);
|
||||
constructor(minecraft, world, id) {
|
||||
super(minecraft, world, id);
|
||||
|
||||
this.jumpTicks = 0;
|
||||
|
||||
@@ -70,6 +70,28 @@ export default class EntityLiving extends Entity {
|
||||
--this.jumpTicks;
|
||||
}
|
||||
|
||||
if (this.rotationPositionIncrements > 0) {
|
||||
// Interpolate the position and rotation
|
||||
let x = this.x + (this.targetX - this.x) / this.rotationPositionIncrements;
|
||||
let y = this.y + (this.targetY - this.y) / this.rotationPositionIncrements;
|
||||
let z = this.z + (this.targetZ - this.z) / this.rotationPositionIncrements;
|
||||
|
||||
// Update yaw and pitch
|
||||
let yaw = MathHelper.wrapAngleTo180(this.targetYaw - this.rotationYaw);
|
||||
this.rotationYaw = this.rotationYaw + yaw / this.rotationPositionIncrements;
|
||||
this.rotationPitch = (this.rotationPitch + (this.targetPitch - this.rotationPitch) / this.rotationPositionIncrements);
|
||||
|
||||
// Decrement position increments
|
||||
this.rotationPositionIncrements--;
|
||||
|
||||
// Update position
|
||||
this.setPosition(x, y, z);
|
||||
this.setRotation(this.rotationYaw, this.rotationPitch);
|
||||
}
|
||||
|
||||
// TODO Find the right spot to update this
|
||||
this.rotationYawHead = this.rotationYaw;
|
||||
|
||||
// Stop if too slow
|
||||
if (Math.abs(this.motionX) < 0.003) {
|
||||
this.motionX = 0.0;
|
||||
@@ -81,8 +103,6 @@ export default class EntityLiving extends Entity {
|
||||
this.motionZ = 0.0;
|
||||
}
|
||||
|
||||
this.rotationYawHead = this.rotationYaw;
|
||||
|
||||
// Jump
|
||||
if (this.jumping) {
|
||||
if (this.isInWater()) {
|
||||
@@ -174,6 +194,15 @@ export default class EntityLiving extends Entity {
|
||||
}
|
||||
}
|
||||
|
||||
setTargetPositionAndRotation(x, y, z, yaw, pitch, increments) {
|
||||
this.targetX = x;
|
||||
this.targetY = y;
|
||||
this.targetZ = z;
|
||||
this.targetYaw = yaw;
|
||||
this.targetPitch = pitch;
|
||||
this.rotationPositionIncrements = increments;
|
||||
}
|
||||
|
||||
swingArm() {
|
||||
let swingAnimationEnd = 6;
|
||||
if (!this.isSwingInProgress || this.swingProgressInt >= swingAnimationEnd / 2 || this.swingProgressInt < 0) {
|
||||
@@ -217,4 +246,9 @@ export default class EntityLiving extends Entity {
|
||||
return value - wrapped;
|
||||
}
|
||||
|
||||
setRotationYawHead(yaw) {
|
||||
this.targetYaw = yaw; // TODO should be rotationYawHead
|
||||
// this.rotationYawHead = yaw;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -10,8 +10,8 @@ export default class PlayerEntity extends EntityLiving {
|
||||
|
||||
static name = "PlayerEntity";
|
||||
|
||||
constructor(minecraft, world) {
|
||||
super(minecraft, world);
|
||||
constructor(minecraft, world, id) {
|
||||
super(minecraft, world, id);
|
||||
|
||||
this.inventory = new InventoryPlayer();
|
||||
this.username = "Player";
|
||||
@@ -73,73 +73,7 @@ export default class PlayerEntity extends EntityLiving {
|
||||
}
|
||||
|
||||
onLivingUpdate() {
|
||||
this.prevCameraYaw = this.cameraYaw;
|
||||
this.prevCameraPitch = this.cameraPitch;
|
||||
|
||||
if (this.sprintToggleTimer > 0) {
|
||||
--this.sprintToggleTimer;
|
||||
}
|
||||
if (this.flyToggleTimer > 0) {
|
||||
--this.flyToggleTimer;
|
||||
}
|
||||
|
||||
let prevMoveForward = this.moveForward;
|
||||
let prevJumping = this.jumping;
|
||||
|
||||
this.updateKeyboardInput();
|
||||
|
||||
// Toggle jumping
|
||||
if (!prevJumping && this.jumping) {
|
||||
if (this.flyToggleTimer === 0) {
|
||||
this.flyToggleTimer = 7;
|
||||
} else {
|
||||
this.flying = !this.flying;
|
||||
this.flyToggleTimer = 0;
|
||||
|
||||
this.updateFOVModifier();
|
||||
}
|
||||
}
|
||||
|
||||
// Toggle sprint
|
||||
if (prevMoveForward === 0 && this.moveForward > 0) {
|
||||
if (this.sprintToggleTimer === 0) {
|
||||
this.sprintToggleTimer = 7;
|
||||
} else {
|
||||
this.sprinting = true;
|
||||
this.sprintToggleTimer = 0;
|
||||
|
||||
this.updateFOVModifier();
|
||||
}
|
||||
}
|
||||
|
||||
if (this.sprinting && (this.moveForward <= 0 || this.collision || this.sneaking)) {
|
||||
this.sprinting = false;
|
||||
|
||||
this.updateFOVModifier();
|
||||
}
|
||||
|
||||
super.onLivingUpdate();
|
||||
|
||||
this.jumpMovementFactor = this.speedInAir;
|
||||
|
||||
if (this.sprinting) {
|
||||
this.jumpMovementFactor = this.jumpMovementFactor + this.speedInAir * 0.3;
|
||||
}
|
||||
|
||||
let speedXZ = Math.sqrt(this.motionX * this.motionX + this.motionZ * this.motionZ);
|
||||
let speedY = (Math.atan(-this.motionY * 0.2) * 15.0);
|
||||
|
||||
if (speedXZ > 0.1) {
|
||||
speedXZ = 0.1;
|
||||
}
|
||||
if (!this.onGround || this.health <= 0.0) {
|
||||
speedXZ = 0.0;
|
||||
}
|
||||
if (this.onGround || this.health <= 0.0) {
|
||||
speedY = 0.0;
|
||||
}
|
||||
this.cameraYaw += (speedXZ - this.cameraYaw) * 0.4;
|
||||
this.cameraPitch += (speedY - this.cameraPitch) * 0.8;
|
||||
}
|
||||
|
||||
isInWater() {
|
||||
@@ -167,7 +101,7 @@ export default class PlayerEntity extends EntityLiving {
|
||||
|
||||
travelFlying(forward, vertical, strafe) {
|
||||
// Fly move up and down
|
||||
if (this.sneaking) {
|
||||
if (this.isSneaking()) {
|
||||
this.moveStrafing = strafe / 0.3;
|
||||
this.moveForward = forward / 0.3;
|
||||
this.motionY -= this.flySpeed * 3.0;
|
||||
@@ -205,40 +139,42 @@ export default class PlayerEntity extends EntityLiving {
|
||||
}
|
||||
|
||||
travel(forward, vertical, strafe) {
|
||||
let prevSlipperiness = this.getBlockSlipperiness() * 0.91;
|
||||
let isSlow = this.onGround && this.isSneaking();
|
||||
|
||||
let prevX = this.x;
|
||||
let prevZ = this.z;
|
||||
|
||||
let isSlow = this.onGround && this.sneaking;
|
||||
if (this === this.world.minecraft.player) {
|
||||
let prevSlipperiness = this.getBlockSlipperiness() * 0.91;
|
||||
|
||||
let value = 0.16277136 / (prevSlipperiness * prevSlipperiness * prevSlipperiness);
|
||||
let friction;
|
||||
let value = 0.16277136 / (prevSlipperiness * prevSlipperiness * prevSlipperiness);
|
||||
let friction;
|
||||
|
||||
if (this.onGround) {
|
||||
friction = this.getAIMoveSpeed() * value;
|
||||
} else {
|
||||
friction = this.jumpMovementFactor;
|
||||
if (this.onGround) {
|
||||
friction = this.getAIMoveSpeed() * value;
|
||||
} else {
|
||||
friction = this.jumpMovementFactor;
|
||||
}
|
||||
|
||||
this.moveRelative(forward, vertical, strafe, friction);
|
||||
|
||||
// Get new speed
|
||||
let slipperiness = this.getBlockSlipperiness() * 0.91;
|
||||
|
||||
// Move
|
||||
this.collision = this.moveCollide(-this.motionX, this.motionY, -this.motionZ);
|
||||
|
||||
// Gravity
|
||||
if (!this.flying) {
|
||||
this.motionY -= 0.08;
|
||||
}
|
||||
|
||||
// Decrease motion
|
||||
this.motionX *= slipperiness;
|
||||
this.motionY *= 0.98;
|
||||
this.motionZ *= slipperiness;
|
||||
}
|
||||
|
||||
this.moveRelative(forward, vertical, strafe, friction);
|
||||
|
||||
// Get new speed
|
||||
let slipperiness = this.getBlockSlipperiness() * 0.91;
|
||||
|
||||
// Move
|
||||
this.collision = this.moveCollide(-this.motionX, this.motionY, -this.motionZ);
|
||||
|
||||
// Gravity
|
||||
if (!this.flying) {
|
||||
this.motionY -= 0.08;
|
||||
}
|
||||
|
||||
// Decrease motion
|
||||
this.motionX *= slipperiness;
|
||||
this.motionY *= 0.98;
|
||||
this.motionZ *= slipperiness;
|
||||
|
||||
// Step sound
|
||||
if (!isSlow) {
|
||||
let blockX = MathHelper.floor(this.x);
|
||||
@@ -254,11 +190,13 @@ export default class PlayerEntity extends EntityLiving {
|
||||
this.nextStepDistance = this.distanceWalked + 1;
|
||||
|
||||
let block = Block.getById(typeId);
|
||||
let sound = block.getSound();
|
||||
if (block !== null) {
|
||||
let sound = block.getSound();
|
||||
|
||||
// Play sound
|
||||
if (!block.isLiquid()) {
|
||||
this.minecraft.soundManager.playSound(sound.getStepSound(), this.x, this.y, this.z, 0.15, sound.getPitch());
|
||||
// Play sound
|
||||
if (!block.isLiquid()) {
|
||||
this.minecraft.soundManager.playSound(sound.getStepSound(), this.x, this.y, this.z, 0.15, sound.getPitch());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -324,7 +262,7 @@ export default class PlayerEntity extends EntityLiving {
|
||||
jumping = true;
|
||||
}
|
||||
if (Keyboard.isKeyDown(this.minecraft.settings.keySprinting)) {
|
||||
if (this.moveForward > 0 && !this.sneaking && !this.sprinting && this.motionX !== 0 && this.motionZ !== 0) {
|
||||
if (this.moveForward > 0 && !this.isSneaking() && !this.sprinting && this.motionX !== 0 && this.motionZ !== 0) {
|
||||
this.sprinting = true;
|
||||
|
||||
this.updateFOVModifier();
|
||||
@@ -344,11 +282,11 @@ export default class PlayerEntity extends EntityLiving {
|
||||
this.moveStrafing = moveStrafe;
|
||||
|
||||
this.jumping = jumping;
|
||||
this.sneaking = sneaking;
|
||||
this.setSneaking(sneaking);
|
||||
}
|
||||
|
||||
getEyeHeight() {
|
||||
return this.sneaking ? 1.50 : 1.62;
|
||||
return this.isSneaking() ? 1.50 : 1.62;
|
||||
}
|
||||
|
||||
updateFOVModifier() {
|
||||
@@ -429,4 +367,7 @@ export default class PlayerEntity extends EntityLiving {
|
||||
return this.world.rayTraceBlocks(from, to);
|
||||
}
|
||||
|
||||
isSprinting() {
|
||||
return this.sprinting;
|
||||
}
|
||||
}
|
||||
@@ -3,11 +3,13 @@ import ClientPlayerMovementPacket from "../network/packet/play/client/ClientPlay
|
||||
import ClientPlayerRotationPacket from "../network/packet/play/client/ClientPlayerRotationPacket.js";
|
||||
import ClientPlayerPositionPacket from "../network/packet/play/client/ClientPlayerPositionPacket.js";
|
||||
import ClientPlayerPositionRotationPacket from "../network/packet/play/client/ClientPlayerPositionRotationPacket.js";
|
||||
import ClientPlayerStatePacket from "../network/packet/play/client/ClientPlayerStatePacket.js";
|
||||
import ClientSwingArmPacket from "../network/packet/play/client/ClientSwingArmPacket.js";
|
||||
|
||||
export default class PlayerEntityMultiplayer extends PlayerEntity {
|
||||
|
||||
constructor(minecraft, world, networkHandler) {
|
||||
super(minecraft, world);
|
||||
constructor(minecraft, world, networkHandler, id) {
|
||||
super(minecraft, world, id);
|
||||
|
||||
this.networkHandler = networkHandler;
|
||||
|
||||
@@ -19,6 +21,9 @@ export default class PlayerEntityMultiplayer extends PlayerEntity {
|
||||
|
||||
this.lastReportedYaw = 0;
|
||||
this.lastReportedPitch = 0;
|
||||
|
||||
this.serverSprintState = false;
|
||||
this.serverSneakState = false;
|
||||
}
|
||||
|
||||
onUpdate() {
|
||||
@@ -26,7 +31,98 @@ export default class PlayerEntityMultiplayer extends PlayerEntity {
|
||||
this.onUpdateWalkingPlayer();
|
||||
}
|
||||
|
||||
swingArm() {
|
||||
super.swingArm();
|
||||
this.networkHandler.sendPacket(new ClientSwingArmPacket());
|
||||
}
|
||||
|
||||
onLivingUpdate() {
|
||||
this.prevCameraYaw = this.cameraYaw;
|
||||
this.prevCameraPitch = this.cameraPitch;
|
||||
|
||||
if (this.sprintToggleTimer > 0) {
|
||||
--this.sprintToggleTimer;
|
||||
}
|
||||
if (this.flyToggleTimer > 0) {
|
||||
--this.flyToggleTimer;
|
||||
}
|
||||
|
||||
let prevMoveForward = this.moveForward;
|
||||
let prevJumping = this.jumping;
|
||||
|
||||
this.updateKeyboardInput();
|
||||
|
||||
// Toggle jumping
|
||||
if (!prevJumping && this.jumping) {
|
||||
if (this.flyToggleTimer === 0) {
|
||||
this.flyToggleTimer = 7;
|
||||
} else {
|
||||
this.flying = !this.flying;
|
||||
this.flyToggleTimer = 0;
|
||||
|
||||
this.updateFOVModifier();
|
||||
}
|
||||
}
|
||||
|
||||
// Toggle sprint
|
||||
if (prevMoveForward === 0 && this.moveForward > 0) {
|
||||
if (this.sprintToggleTimer === 0) {
|
||||
this.sprintToggleTimer = 7;
|
||||
} else {
|
||||
this.sprinting = true;
|
||||
this.sprintToggleTimer = 0;
|
||||
|
||||
this.updateFOVModifier();
|
||||
}
|
||||
}
|
||||
|
||||
if (this.sprinting && (this.moveForward <= 0 || this.collision || this.isSneaking())) {
|
||||
this.sprinting = false;
|
||||
|
||||
this.updateFOVModifier();
|
||||
}
|
||||
|
||||
super.onLivingUpdate();
|
||||
|
||||
this.jumpMovementFactor = this.speedInAir;
|
||||
|
||||
if (this.sprinting) {
|
||||
this.jumpMovementFactor = this.jumpMovementFactor + this.speedInAir * 0.3;
|
||||
}
|
||||
|
||||
let speedXZ = Math.sqrt(this.motionX * this.motionX + this.motionZ * this.motionZ);
|
||||
let speedY = (Math.atan(-this.motionY * 0.2) * 15.0);
|
||||
|
||||
if (speedXZ > 0.1) {
|
||||
speedXZ = 0.1;
|
||||
}
|
||||
if (!this.onGround || this.health <= 0.0) {
|
||||
speedXZ = 0.0;
|
||||
}
|
||||
if (this.onGround || this.health <= 0.0) {
|
||||
speedY = 0.0;
|
||||
}
|
||||
this.cameraYaw += (speedXZ - this.cameraYaw) * 0.4;
|
||||
this.cameraPitch += (speedY - this.cameraPitch) * 0.8;
|
||||
}
|
||||
|
||||
onUpdateWalkingPlayer() {
|
||||
// Send sprinting to server
|
||||
let isSprinting = this.isSprinting();
|
||||
if (isSprinting !== this.serverSprintState) {
|
||||
let state = isSprinting ? ClientPlayerStatePacket.START_SPRINTING : ClientPlayerStatePacket.STOP_SPRINTING;
|
||||
this.networkHandler.sendPacket(new ClientPlayerStatePacket(this.id, state));
|
||||
this.serverSprintState = isSprinting;
|
||||
}
|
||||
|
||||
// Send sneaking to server
|
||||
let isSneaking = this.isSneaking();
|
||||
if (isSneaking !== this.serverSneakState) {
|
||||
let state = isSneaking ? ClientPlayerStatePacket.START_SNEAKING : ClientPlayerStatePacket.STOP_SNEAKING;
|
||||
this.networkHandler.sendPacket(new ClientPlayerStatePacket(this.id, state));
|
||||
this.serverSneakState = isSneaking;
|
||||
}
|
||||
|
||||
let movementX = this.x - this.lastReportedX;
|
||||
let movementY = this.y - this.lastReportedY;
|
||||
let movementZ = this.z - this.lastReportedZ;
|
||||
@@ -37,6 +133,7 @@ export default class PlayerEntityMultiplayer extends PlayerEntity {
|
||||
let reportPosition = movementX * movementX + movementY * movementY + movementZ * movementZ > 9.0E-4 || this.positionUpdateTicks >= 20;
|
||||
let reportRotation = movementYaw !== 0.0 || movementPitch !== 0.0;
|
||||
|
||||
// Send position and rotation to server
|
||||
if (reportPosition && reportRotation) {
|
||||
this.networkHandler.sendPacket(new ClientPlayerPositionRotationPacket(this.onGround, this.x, this.y, this.z, this.rotationYaw, this.rotationPitch));
|
||||
} else if (reportPosition) {
|
||||
|
||||
@@ -2,6 +2,7 @@ import ByteBuf from "./util/ByteBuf.js";
|
||||
import PacketRegistry from "./PacketRegistry.js";
|
||||
import ProtocolState from "./ProtocolState.js";
|
||||
import {require} from "../../../../Start.js";
|
||||
import MissingPackets from "../../util/MissingPackets.js";
|
||||
|
||||
export default class NetworkManager {
|
||||
|
||||
@@ -204,7 +205,7 @@ export default class NetworkManager {
|
||||
let clazz = this.registry.getServerBoundById(this.protocolState, packetId);
|
||||
if (clazz === null) {
|
||||
if (NetworkManager.DEBUG) {
|
||||
console.log("[Network] [IN] Unknown packet id: " + packetId + " (0x" + packetId.toString(16) + ")");
|
||||
console.log("[Network] [IN] Unknown packet id: " + packetId + " (0x" + packetId.toString(16) + ") (" + new MissingPackets().get(packetId) + ")");
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
|
||||
@@ -24,6 +24,20 @@ import ServerDisconnectPacket from "./packet/play/server/ServerDisconnectPacket.
|
||||
import ServerPlayerPositionRotationPacket from "./packet/play/server/ServerPlayerPositionRotationPacket.js";
|
||||
import ServerPlayerListEntryPacket from "./packet/play/server/ServerPlayerListEntryPacket.js";
|
||||
import ServerPlayerListDataPacket from "./packet/play/server/ServerPlayerListDataPacket.js";
|
||||
import ServerSpawnPlayerPacket from "./packet/play/server/ServerSpawnPlayerPacket.js";
|
||||
import ServerEntityPositionRotationPacket from "./packet/play/server/ServerEntityPositionRotationPacket.js";
|
||||
import ServerEntityMovementPacket from "./packet/play/server/ServerEntityMovementPacket.js";
|
||||
import ServerEntityRotationPacket from "./packet/play/server/ServerEntityRotationPacket.js";
|
||||
import ServerEntityPositionPacket from "./packet/play/server/ServerEntityPositionPacket.js";
|
||||
import ServerEntityTeleportPacket from "./packet/play/server/ServerEntityTeleportPacket.js";
|
||||
import ServerDestroyEntitiesPacket from "./packet/play/server/ServerDestroyEntitiesPacket.js";
|
||||
import ServerEntityHeadLookPacket from "./packet/play/server/ServerEntityHeadLookPacket.js";
|
||||
import ClientPlayerStatePacket from "./packet/play/client/ClientPlayerStatePacket.js";
|
||||
import ClientSwingArmPacket from "./packet/play/client/ClientSwingArmPacket.js";
|
||||
import ServerAnimationPacket from "./packet/play/server/ServerAnimationPacket.js";
|
||||
import ServerEntityMetadataPacket from "./packet/play/server/ServerEntityMetadataPacket.js";
|
||||
import ServerConfirmTransactionPacket from "./packet/play/server/ServerConfirmTransactionPacket.js";
|
||||
import ClientConfirmTransactionPacket from "./packet/play/client/ClientConfirmTransactionPacket.js";
|
||||
|
||||
export default class PacketRegistry {
|
||||
|
||||
@@ -52,9 +66,20 @@ export default class PacketRegistry {
|
||||
this.registerServer(ProtocolState.PLAY, 0x01, ServerJoinGamePacket);
|
||||
this.registerServer(ProtocolState.PLAY, 0x02, ServerChatPacket);
|
||||
this.registerServer(ProtocolState.PLAY, 0x08, ServerPlayerPositionRotationPacket);
|
||||
this.registerServer(ProtocolState.PLAY, 0x0B, ServerAnimationPacket);
|
||||
this.registerServer(ProtocolState.PLAY, 0x0C, ServerSpawnPlayerPacket);
|
||||
this.registerServer(ProtocolState.PLAY, 0x13, ServerDestroyEntitiesPacket);
|
||||
this.registerServer(ProtocolState.PLAY, 0x14, ServerEntityMovementPacket);
|
||||
this.registerServer(ProtocolState.PLAY, 0x15, ServerEntityPositionPacket);
|
||||
this.registerServer(ProtocolState.PLAY, 0x16, ServerEntityRotationPacket);
|
||||
this.registerServer(ProtocolState.PLAY, 0x17, ServerEntityPositionRotationPacket);
|
||||
this.registerServer(ProtocolState.PLAY, 0x18, ServerEntityTeleportPacket);
|
||||
this.registerServer(ProtocolState.PLAY, 0x19, ServerEntityHeadLookPacket);
|
||||
this.registerServer(ProtocolState.PLAY, 0x1C, ServerEntityMetadataPacket);
|
||||
this.registerServer(ProtocolState.PLAY, 0x21, ServerChunkDataPacket);
|
||||
this.registerServer(ProtocolState.PLAY, 0x23, ServerBlockChangePacket);
|
||||
this.registerServer(ProtocolState.PLAY, 0x26, ServerMultiChunkDataPacket);
|
||||
this.registerServer(ProtocolState.PLAY, 0x32, ServerConfirmTransactionPacket);
|
||||
this.registerServer(ProtocolState.PLAY, 0x38, ServerPlayerListEntryPacket);
|
||||
this.registerServer(ProtocolState.PLAY, 0x40, ServerDisconnectPacket);
|
||||
this.registerServer(ProtocolState.PLAY, 0x47, ServerPlayerListDataPacket);
|
||||
@@ -65,6 +90,9 @@ export default class PacketRegistry {
|
||||
this.registerClient(ProtocolState.PLAY, 0x04, ClientPlayerPositionPacket);
|
||||
this.registerClient(ProtocolState.PLAY, 0x05, ClientPlayerRotationPacket);
|
||||
this.registerClient(ProtocolState.PLAY, 0x06, ClientPlayerPositionRotationPacket);
|
||||
this.registerClient(ProtocolState.PLAY, 0x0A, ClientSwingArmPacket);
|
||||
this.registerClient(ProtocolState.PLAY, 0x0B, ClientPlayerStatePacket);
|
||||
this.registerClient(ProtocolState.PLAY, 0x0F, ClientConfirmTransactionPacket);
|
||||
}
|
||||
|
||||
registerClient(state, id, packet) {
|
||||
|
||||
@@ -7,7 +7,7 @@ export default class PlayerController {
|
||||
}
|
||||
|
||||
createPlayer(world) {
|
||||
return new PlayerEntity(this.minecraft, world);
|
||||
return new PlayerEntity(this.minecraft, world, 0);
|
||||
}
|
||||
|
||||
sendChatMessage(message) {
|
||||
|
||||
@@ -4,14 +4,15 @@ import ClientChatPacket from "../packet/play/client/ClientChatPacket.js";
|
||||
|
||||
export default class PlayerControllerMultiplayer extends PlayerController {
|
||||
|
||||
constructor(minecraft, networkHandler) {
|
||||
constructor(minecraft, networkHandler, entityId) {
|
||||
super(minecraft);
|
||||
|
||||
this.entityId = entityId;
|
||||
this.networkHandler = networkHandler;
|
||||
}
|
||||
|
||||
createPlayer(world) {
|
||||
return new PlayerEntityMultiplayer(this.minecraft, world, this.networkHandler);
|
||||
return new PlayerEntityMultiplayer(this.minecraft, world, this.networkHandler, this.entityId);
|
||||
}
|
||||
|
||||
sendChatMessage(message) {
|
||||
|
||||
@@ -4,6 +4,9 @@ import WorldClient from "../../world/WorldClient.js";
|
||||
import ClientKeepAlivePacket from "../packet/play/client/ClientKeepAlivePacket.js";
|
||||
import PlayerControllerMultiplayer from "../controller/PlayerControllerMultiplayer.js";
|
||||
import ClientPlayerPositionRotationPacket from "../packet/play/client/ClientPlayerPositionRotationPacket.js";
|
||||
import PlayerEntity from "../../entity/PlayerEntity.js";
|
||||
import ServerAnimationPacket from "../packet/play/server/ServerAnimationPacket.js";
|
||||
import ClientConfirmTransactionPacket from "../packet/play/client/ClientConfirmTransactionPacket.js";
|
||||
|
||||
export default class NetworkPlayHandler extends PacketHandler {
|
||||
|
||||
@@ -22,7 +25,7 @@ export default class NetworkPlayHandler extends PacketHandler {
|
||||
}
|
||||
|
||||
handleJoinGame(packet) {
|
||||
this.minecraft.playerController = new PlayerControllerMultiplayer(this.minecraft, this);
|
||||
this.minecraft.playerController = new PlayerControllerMultiplayer(this.minecraft, this, packet.entityId);
|
||||
let world = new WorldClient(this.minecraft);
|
||||
this.minecraft.loadWorld(world);
|
||||
}
|
||||
@@ -108,10 +111,110 @@ export default class NetworkPlayHandler extends PacketHandler {
|
||||
pitch += player.rotationPitch;
|
||||
}
|
||||
|
||||
player.setPosition(x, y, z);
|
||||
player.setRotation(yaw, pitch);
|
||||
player.setPositionAndRotation(x, y, z, yaw, pitch);
|
||||
this.networkManager.sendPacket(new ClientPlayerPositionRotationPacket(true, player.x, player.boundingBox.minY, player.z, player.rotationYaw, player.rotationPitch));
|
||||
}
|
||||
|
||||
this.networkManager.sendPacket(new ClientPlayerPositionRotationPacket(player.x, player.y, player.z, player.rotationYaw, player.rotationPitch, player.onGround));
|
||||
handleServerSpawnPlayer(packet) {
|
||||
let world = this.minecraft.world;
|
||||
let entity = new PlayerEntity(this.minecraft, world, packet.getEntityId());
|
||||
|
||||
entity.serverPositionX = packet.getX();
|
||||
entity.serverPositionY = packet.getY();
|
||||
entity.serverPositionZ = packet.getZ();
|
||||
|
||||
let x = entity.serverPositionX / 32;
|
||||
let y = entity.serverPositionY / 32;
|
||||
let z = entity.serverPositionZ / 32;
|
||||
|
||||
let yaw = packet.rotation ? packet.getYaw() * 360 / 256 : entity.rotationYaw;
|
||||
let pitch = packet.rotation ? packet.getPitch() * 360 / 256 : entity.rotationPitch;
|
||||
|
||||
entity.setPosition(x, y, z);
|
||||
entity.setRotation(yaw, pitch);
|
||||
|
||||
world.addEntity(entity);
|
||||
}
|
||||
|
||||
handleEntityMovement(packet) {
|
||||
let entity = this.minecraft.world.getEntityById(packet.getEntityId());
|
||||
if (entity !== null) {
|
||||
entity.serverPositionX += packet.getX();
|
||||
entity.serverPositionY += packet.getY();
|
||||
entity.serverPositionZ += packet.getZ();
|
||||
|
||||
let x = entity.serverPositionX / 32;
|
||||
let y = entity.serverPositionY / 32;
|
||||
let z = entity.serverPositionZ / 32;
|
||||
|
||||
let yaw = packet.rotation ? packet.getYaw() * 360 / 256 : entity.rotationYaw;
|
||||
let pitch = packet.rotation ? packet.getPitch() * 360 / 256 : entity.rotationPitch;
|
||||
|
||||
entity.setTargetPositionAndRotation(x, y, z, yaw, pitch, 3);
|
||||
|
||||
entity.onGround = packet.isOnGround();
|
||||
}
|
||||
}
|
||||
|
||||
handleEntityTeleport(packet) {
|
||||
let entity = this.minecraft.world.getEntityById(packet.getEntityId());
|
||||
if (entity !== null) {
|
||||
entity.serverPositionX = packet.getX();
|
||||
entity.serverPositionY = packet.getY();
|
||||
entity.serverPositionZ = packet.getZ();
|
||||
|
||||
let x = entity.serverPositionX / 32;
|
||||
let y = entity.serverPositionY / 32;
|
||||
let z = entity.serverPositionZ / 32;
|
||||
|
||||
let yaw = packet.getYaw() * 360 / 256;
|
||||
let pitch = packet.getPitch() * 360 / 256;
|
||||
|
||||
if (Math.abs(entity.x - x) < 0.03125 && Math.abs(entity.y - y) < 0.015625 && Math.abs(entity.z - z) < 0.03125) {
|
||||
entity.setTargetPositionAndRotation(entity.x, entity.y, entity.z, yaw, pitch, 3);
|
||||
} else {
|
||||
entity.setTargetPositionAndRotation(x, y, z, yaw, pitch, 3);
|
||||
}
|
||||
|
||||
entity.onGround = packet.isOnGround();
|
||||
}
|
||||
}
|
||||
|
||||
handleEntityMetadata(packet) {
|
||||
let entity = this.minecraft.world.getEntityById(packet.getEntityId());
|
||||
if (entity !== null) {
|
||||
entity.updateMetaData(packet.getMetaData());
|
||||
}
|
||||
}
|
||||
|
||||
handleEntityHeadLook(packet) {
|
||||
let entity = this.minecraft.world.getEntityById(packet.getEntityId());
|
||||
if (entity !== null) {
|
||||
entity.setRotationYawHead(packet.getHeadYaw() * 360 / 256);
|
||||
}
|
||||
}
|
||||
|
||||
handleAnimation(packet) {
|
||||
let entity = this.minecraft.world.getEntityById(packet.getEntityId());
|
||||
if (entity !== null) {
|
||||
switch (packet.getAnimation()) {
|
||||
case ServerAnimationPacket.SWING_ARM:
|
||||
entity.swingArm();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
handleDestroyEntities(packet) {
|
||||
for (let entityId of packet.getEntityIds()) {
|
||||
this.minecraft.world.removeEntityById(entityId);
|
||||
}
|
||||
}
|
||||
|
||||
handleConfirmTransaction(packet) {
|
||||
if (!packet.isAccepted()) {
|
||||
this.networkManager.sendPacket(new ClientConfirmTransactionPacket(packet.getWindowId(), packet.getActionId(), true));
|
||||
}
|
||||
}
|
||||
|
||||
handleChunkData(packet) {
|
||||
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
import Packet from "../../../Packet.js";
|
||||
|
||||
export default class ClientConfirmTransactionPacket extends Packet {
|
||||
|
||||
constructor(windowId, actionId, accepted) {
|
||||
super();
|
||||
|
||||
this.windowId = windowId;
|
||||
this.actionId = actionId;
|
||||
this.accepted = accepted;
|
||||
}
|
||||
|
||||
write(buffer) {
|
||||
buffer.writeByte(this.windowId);
|
||||
buffer.writeShort(this.actionId);
|
||||
buffer.writeByte(this.accepted ? 1 : 0);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
import Packet from "../../../Packet.js";
|
||||
|
||||
export default class ClientPlayerStatePacket extends Packet {
|
||||
|
||||
static START_SNEAKING = 0;
|
||||
static STOP_SNEAKING = 1;
|
||||
static STOP_SLEEPING = 2;
|
||||
static START_SPRINTING = 3;
|
||||
static STOP_SPRINTING = 4;
|
||||
static RIDING_JUMP = 5;
|
||||
static OPEN_INVENTORY = 6;
|
||||
|
||||
constructor(entityId, state, jumpBoost = 0) {
|
||||
super();
|
||||
|
||||
this.entityId = entityId;
|
||||
this.state = state;
|
||||
this.jumpBoost = jumpBoost;
|
||||
}
|
||||
|
||||
write(buffer) {
|
||||
buffer.writeVarInt(this.entityId);
|
||||
buffer.writeByte(this.state);
|
||||
buffer.writeVarInt(this.jumpBoost);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
import Packet from "../../../Packet.js";
|
||||
|
||||
export default class ClientSwingArmPacket extends Packet {
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
import Packet from "../../../Packet.js";
|
||||
|
||||
export default class ServerAnimationPacket extends Packet {
|
||||
|
||||
static SWING_ARM = 0;
|
||||
static DAMAGE = 1;
|
||||
static LEAVE_BED = 2;
|
||||
static EAT_FOOD = 3;
|
||||
static CRITICAL_HIT = 4;
|
||||
static ENCHANTMENT_CRITICAL_HIT = 5;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.entityId = 0;
|
||||
this.animation = 0;
|
||||
}
|
||||
|
||||
read(buffer) {
|
||||
this.entityId = buffer.readVarInt();
|
||||
this.animation = buffer.readByte();
|
||||
}
|
||||
|
||||
handle(handler) {
|
||||
handler.handleAnimation(this);
|
||||
}
|
||||
|
||||
getEntityId() {
|
||||
return this.entityId;
|
||||
}
|
||||
|
||||
getAnimation() {
|
||||
return this.animation;
|
||||
}
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
import Packet from "../../../Packet.js";
|
||||
|
||||
export default class ServerConfirmTransactionPacket extends Packet {
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.windowId = 0;
|
||||
this.actionId = 0;
|
||||
this.accepted = false;
|
||||
}
|
||||
|
||||
read(buffer) {
|
||||
this.windowId = buffer.readByte();
|
||||
this.actionId = buffer.readShort();
|
||||
this.accepted = buffer.readBoolean();
|
||||
}
|
||||
|
||||
handle(handler) {
|
||||
handler.handleConfirmTransaction(this);
|
||||
}
|
||||
|
||||
getWindowId() {
|
||||
return this.windowId;
|
||||
}
|
||||
|
||||
getActionId() {
|
||||
return this.actionId;
|
||||
}
|
||||
|
||||
isAccepted() {
|
||||
return this.accepted;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
import Packet from "../../../Packet.js";
|
||||
|
||||
export default class ServerDestroyEntitiesPacket extends Packet {
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.entityIds = [];
|
||||
}
|
||||
|
||||
read(buffer) {
|
||||
let amount = buffer.readVarInt();
|
||||
for (let i = 0; i < amount; i++) {
|
||||
this.entityIds.push(buffer.readVarInt());
|
||||
}
|
||||
}
|
||||
|
||||
handle(handler) {
|
||||
handler.handleDestroyEntities(this);
|
||||
}
|
||||
|
||||
getEntityIds() {
|
||||
return this.entityIds;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
import Packet from "../../../Packet.js";
|
||||
|
||||
export default class ServerEntityHeadLookPacket extends Packet {
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.entityId = 0;
|
||||
this.headYaw = 0;
|
||||
}
|
||||
|
||||
read(buffer) {
|
||||
this.entityId = buffer.readVarInt();
|
||||
this.headYaw = buffer.readByte();
|
||||
}
|
||||
|
||||
handle(handler) {
|
||||
handler.handleEntityHeadLook(this);
|
||||
}
|
||||
|
||||
getEntityId() {
|
||||
return this.entityId;
|
||||
}
|
||||
|
||||
getHeadYaw() {
|
||||
return this.headYaw;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
import Packet from "../../../Packet.js";
|
||||
|
||||
export default class ServerEntityMetadataPacket extends Packet {
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.entityId = 0;
|
||||
this.metaData = null;
|
||||
}
|
||||
|
||||
read(buffer) {
|
||||
this.entityId = buffer.readVarInt();
|
||||
this.metaData = buffer.readMetaData();
|
||||
}
|
||||
|
||||
handle(handler) {
|
||||
handler.handleEntityMetadata(this);
|
||||
}
|
||||
|
||||
getEntityId() {
|
||||
return this.entityId;
|
||||
}
|
||||
|
||||
getMetaData() {
|
||||
return this.metaData;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
import Packet from "../../../Packet.js";
|
||||
|
||||
export default class ServerEntityMovementPacket extends Packet {
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.position = false;
|
||||
this.rotation = false;
|
||||
|
||||
this.entityId = 0;
|
||||
|
||||
this.onGround = false;
|
||||
|
||||
this.x = 0;
|
||||
this.y = 0;
|
||||
this.z = 0;
|
||||
|
||||
this.yaw = 0;
|
||||
this.pitch = 0;
|
||||
}
|
||||
|
||||
read(buffer) {
|
||||
this.entityId = buffer.readVarInt();
|
||||
|
||||
if (this.position) {
|
||||
this.x = buffer.readByte();
|
||||
this.y = buffer.readByte();
|
||||
this.z = buffer.readByte();
|
||||
}
|
||||
|
||||
if (this.rotation) {
|
||||
this.yaw = buffer.readByte();
|
||||
this.pitch = buffer.readByte();
|
||||
}
|
||||
|
||||
this.onGround = buffer.readBoolean();
|
||||
}
|
||||
|
||||
handle(packetHandler) {
|
||||
packetHandler.handleEntityMovement(this);
|
||||
}
|
||||
|
||||
getEntityId() {
|
||||
return this.entityId;
|
||||
}
|
||||
|
||||
getX() {
|
||||
return this.x;
|
||||
}
|
||||
|
||||
getY() {
|
||||
return this.y;
|
||||
}
|
||||
|
||||
getZ() {
|
||||
return this.z;
|
||||
}
|
||||
|
||||
getYaw() {
|
||||
return this.yaw;
|
||||
}
|
||||
|
||||
getPitch() {
|
||||
return this.pitch;
|
||||
}
|
||||
|
||||
isOnGround() {
|
||||
return this.onGround;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
import ServerEntityMovementPacket from "./ServerEntityMovementPacket.js";
|
||||
|
||||
export default class ServerEntityPositionPacket extends ServerEntityMovementPacket {
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.position = true;
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
import ServerEntityMovementPacket from "./ServerEntityMovementPacket.js";
|
||||
|
||||
export default class ServerEntityPositionRotationPacket extends ServerEntityMovementPacket {
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.position = true;
|
||||
this.position = true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
import ServerEntityMovementPacket from "./ServerEntityMovementPacket.js";
|
||||
|
||||
export default class ServerEntityRotationPacket extends ServerEntityMovementPacket {
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.rotation = true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
import Packet from "../../../Packet.js";
|
||||
|
||||
export default class ServerEntityTeleportPacket extends Packet {
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.entityId = 0;
|
||||
|
||||
this.x = 0;
|
||||
this.y = 0;
|
||||
this.z = 0;
|
||||
|
||||
this.yaw = 0;
|
||||
this.pitch = 0;
|
||||
|
||||
this.onGround = false;
|
||||
}
|
||||
|
||||
read(buffer) {
|
||||
this.entityId = buffer.readVarInt();
|
||||
this.x = buffer.readInt();
|
||||
this.y = buffer.readInt();
|
||||
this.z = buffer.readInt();
|
||||
this.yaw = buffer.readByte();
|
||||
this.pitch = buffer.readByte();
|
||||
this.onGround = buffer.readBoolean();
|
||||
}
|
||||
|
||||
handle(packetHandler) {
|
||||
packetHandler.handleEntityTeleport(this);
|
||||
}
|
||||
|
||||
getEntityId() {
|
||||
return this.entityId;
|
||||
}
|
||||
|
||||
getX() {
|
||||
return this.x;
|
||||
}
|
||||
|
||||
getY() {
|
||||
return this.y;
|
||||
}
|
||||
|
||||
getZ() {
|
||||
return this.z;
|
||||
}
|
||||
|
||||
getYaw() {
|
||||
return this.yaw;
|
||||
}
|
||||
|
||||
getPitch() {
|
||||
return this.pitch;
|
||||
}
|
||||
|
||||
isOnGround() {
|
||||
return this.onGround;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
import Packet from "../../../Packet.js";
|
||||
|
||||
export default class ServerSpawnPlayerPacket extends Packet {
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.entityId = 0;
|
||||
this.uuid = null;
|
||||
|
||||
this.x = 0;
|
||||
this.y = 0;
|
||||
this.z = 0;
|
||||
|
||||
this.yaw = 0;
|
||||
this.pitch = 0;
|
||||
|
||||
this.currentItem = 0;
|
||||
}
|
||||
|
||||
read(buffer) {
|
||||
this.entityId = buffer.readVarInt();
|
||||
this.uuid = buffer.readUUID();
|
||||
|
||||
this.x = buffer.readInt();
|
||||
this.y = buffer.readInt();
|
||||
this.z = buffer.readInt();
|
||||
|
||||
this.yaw = buffer.readByte();
|
||||
this.pitch = buffer.readByte();
|
||||
|
||||
this.currentItem = buffer.readShort();
|
||||
this.metaData = buffer.readMetaData();
|
||||
}
|
||||
|
||||
handle(handler) {
|
||||
handler.handleServerSpawnPlayer(this);
|
||||
}
|
||||
|
||||
getEntityId() {
|
||||
return this.entityId;
|
||||
}
|
||||
|
||||
getUUID() {
|
||||
return this.uuid;
|
||||
}
|
||||
|
||||
getX() {
|
||||
return this.x;
|
||||
}
|
||||
|
||||
getY() {
|
||||
return this.y;
|
||||
}
|
||||
|
||||
getZ() {
|
||||
return this.z;
|
||||
}
|
||||
|
||||
getYaw() {
|
||||
return this.yaw;
|
||||
}
|
||||
|
||||
getPitch() {
|
||||
return this.pitch;
|
||||
}
|
||||
|
||||
getMetaData() {
|
||||
return this.metaData;
|
||||
}
|
||||
|
||||
getCurrentItem() {
|
||||
return this.currentItem;
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,8 @@ import Long from "../../../../../../../libraries/long.js";
|
||||
import BlockPosition from "../../../util/BlockPosition.js";
|
||||
import UUID from "../../../util/UUID.js";
|
||||
import {format} from "../../../../../../../libraries/chat.js";
|
||||
import Vector3 from "../../../util/Vector3.js";
|
||||
import NBTIO from "../../../nbt/NBTIO.js";
|
||||
|
||||
export default class ByteBuf {
|
||||
|
||||
@@ -228,6 +230,79 @@ export default class ByteBuf {
|
||||
return format(JSON.parse(this.readString(32767)));
|
||||
}
|
||||
|
||||
readMetaData() {
|
||||
let metaData = {};
|
||||
|
||||
let data = 0;
|
||||
while ((data = this.readByte()) !== 0x7f) {
|
||||
let typeId = (data & 0xE0) >> 5;
|
||||
let id = data & 0x1F;
|
||||
|
||||
let value = null;
|
||||
switch (typeId) {
|
||||
case 0:
|
||||
value = this.readByte();
|
||||
break;
|
||||
case 1:
|
||||
value = this.readShort();
|
||||
break;
|
||||
case 2:
|
||||
value = this.readInt();
|
||||
break;
|
||||
case 3:
|
||||
value = this.readFloat();
|
||||
break;
|
||||
case 4:
|
||||
value = this.readString();
|
||||
break;
|
||||
case 5:
|
||||
value = this.readItem();
|
||||
break;
|
||||
case 6:
|
||||
value = new BlockPosition(this.readInt(), this.readInt(), this.readInt());
|
||||
break;
|
||||
case 7:
|
||||
value = new Vector3(this.readFloat(), this.readFloat(), this.readFloat());
|
||||
break;
|
||||
default:
|
||||
throw new Error("Unknown meta data type: " + typeId);
|
||||
}
|
||||
metaData[id] = {
|
||||
id: id,
|
||||
type: typeId,
|
||||
value: value
|
||||
};
|
||||
}
|
||||
|
||||
return metaData;
|
||||
}
|
||||
|
||||
readItem() {
|
||||
let item = this.readShort();
|
||||
if (item < 0) {
|
||||
return null;
|
||||
} else {
|
||||
let a = this.readByte();
|
||||
let b = this.readShort();
|
||||
let c = this.readNBT();
|
||||
|
||||
// TODO create item
|
||||
return item;
|
||||
}
|
||||
}
|
||||
|
||||
readNBT() {
|
||||
let position = this.getPosition();
|
||||
|
||||
let tagId = this.readByte();
|
||||
if (tagId === 0) {
|
||||
return null;
|
||||
} else {
|
||||
this.setPosition(position);
|
||||
return NBTIO.readTag(this); // TODO
|
||||
}
|
||||
}
|
||||
|
||||
readableBytes() {
|
||||
return this.array.length - this.pos;
|
||||
}
|
||||
|
||||
@@ -25,8 +25,9 @@ export default class PlayerRenderer extends EntityRenderer {
|
||||
let firstPerson = this.worldRenderer.minecraft.settings.thirdPersonView === 0;
|
||||
let itemId = firstPerson ? this.worldRenderer.itemToRender : entity.inventory.getItemInSelectedSlot();
|
||||
let hasItem = itemId !== 0;
|
||||
let isSelf = entity === this.worldRenderer.minecraft.player;
|
||||
|
||||
if (firstPerson && hasItem) {
|
||||
if (firstPerson && hasItem && isSelf) {
|
||||
super.rebuild(entity);
|
||||
|
||||
// Create new item group and add it to the hand
|
||||
@@ -72,7 +73,12 @@ export default class PlayerRenderer extends EntityRenderer {
|
||||
}
|
||||
this.model.swingProgress = entity.prevSwingProgress + swingProgress * partialTicks;
|
||||
this.model.hasItemInHand = entity.inventory.getItemInSelectedSlot() !== 0;
|
||||
this.model.isSneaking = entity.sneaking;
|
||||
this.model.isSneaking = entity.isSneaking();
|
||||
|
||||
// TODO find a better way
|
||||
if (entity !== this.worldRenderer.minecraft.player) {
|
||||
this.firstPersonGroup.visible = false;
|
||||
}
|
||||
|
||||
super.render(entity, partialTicks);
|
||||
}
|
||||
|
||||
@@ -195,7 +195,7 @@ export default class Chunk {
|
||||
while (y > 0) {
|
||||
let typeId = this.getBlockAt(x, y - 1, z);
|
||||
let block = Block.getById(typeId);
|
||||
let opacity = typeId === 0 ? 0 : block.getOpacity();
|
||||
let opacity = typeId === 0 || block === null ? 0 : block.getOpacity();
|
||||
|
||||
if (opacity !== 0) {
|
||||
break;
|
||||
|
||||
@@ -43,6 +43,11 @@ export default class World {
|
||||
}
|
||||
|
||||
onTick() {
|
||||
// Tick entities
|
||||
for (let i = 0; i < this.entities.length; i++) {
|
||||
this.entities[i].onUpdate();
|
||||
}
|
||||
|
||||
// Update skylight subtracted (To make the night dark)
|
||||
let lightLevel = this.calculateSkylightSubtracted(1.0);
|
||||
if (lightLevel !== this.skylightSubtracted) {
|
||||
@@ -566,8 +571,10 @@ export default class World {
|
||||
|
||||
removeEntityById(id) {
|
||||
let entity = this.getEntityById(id);
|
||||
this.entities.remove(entity);
|
||||
this.group.remove(entity.renderer.group);
|
||||
if (entity !== null) {
|
||||
this.entities.splice(this.entities.indexOf(entity), 1);
|
||||
this.group.remove(entity.renderer.group);
|
||||
}
|
||||
}
|
||||
|
||||
getEntityById(id) {
|
||||
@@ -602,4 +609,10 @@ export default class World {
|
||||
return this.chunkProvider;
|
||||
}
|
||||
|
||||
clearEntities() {
|
||||
for (let entity of this.entities) {
|
||||
this.removeEntityById(entity.id);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
import TagRegistry from "./tag/TagRegistry.js";
|
||||
|
||||
export default class {
|
||||
|
||||
static readTag(buffer) {
|
||||
let id = buffer.readUnsignedByte();
|
||||
if (id === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let nameLength = buffer.readShort();
|
||||
let nameBytes = new Uint8Array(nameLength);
|
||||
buffer.read(nameBytes, nameLength);
|
||||
let name = new TextDecoder().decode(nameBytes);
|
||||
|
||||
let tag = TagRegistry.createInstance(id, name);
|
||||
tag.read(buffer);
|
||||
return tag;
|
||||
}
|
||||
|
||||
static writeTag(buffer, tag) {
|
||||
let nameBytes = new TextEncoder().encode(tag.getName());
|
||||
buffer.writeByte(TagRegistry.getIdFor(tag));
|
||||
buffer.writeShort(nameBytes.length);
|
||||
buffer.write(nameBytes);
|
||||
tag.write(buffer);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
import ByteTag from "./builtin/ByteTag.js";
|
||||
import CompoundTag from "./builtin/CompoundTag.js";
|
||||
import ShortTag from "./builtin/ShortTag.js";
|
||||
import IntTag from "./builtin/IntTag.js";
|
||||
import LongTag from "./builtin/LongTag.js";
|
||||
import FloatTag from "./builtin/FloatTag.js";
|
||||
import DoubleTag from "./builtin/DoubleTag.js";
|
||||
import StringTag from "./builtin/StringTag.js";
|
||||
import ByteArrayTag from "./builtin/ByteArrayTag.js";
|
||||
import ListTag from "./builtin/ListTag.js";
|
||||
import IntArrayTag from "./builtin/IntArrayTag.js";
|
||||
|
||||
export default class TagRegistry {
|
||||
|
||||
static idToTag = new Map();
|
||||
static tagToId = new Map();
|
||||
|
||||
static {
|
||||
TagRegistry.register(1, ByteTag);
|
||||
TagRegistry.register(2, ShortTag);
|
||||
TagRegistry.register(3, IntTag);
|
||||
TagRegistry.register(4, LongTag);
|
||||
TagRegistry.register(5, FloatTag);
|
||||
TagRegistry.register(6, DoubleTag);
|
||||
TagRegistry.register(7, ByteArrayTag);
|
||||
TagRegistry.register(8, StringTag);
|
||||
TagRegistry.register(9, ListTag);
|
||||
TagRegistry.register(10, CompoundTag);
|
||||
TagRegistry.register(11, IntArrayTag);
|
||||
}
|
||||
|
||||
static register(id, tag) {
|
||||
TagRegistry.idToTag.set(id, tag);
|
||||
TagRegistry.tagToId.set(tag, id);
|
||||
}
|
||||
|
||||
static getIdFor(clazz) {
|
||||
let id = TagRegistry.tagToId.get(clazz);
|
||||
if (typeof id === "undefined") {
|
||||
return -1;
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
static getClassFor(id) {
|
||||
let clazz = TagRegistry.idToTag.get(id);
|
||||
if (typeof clazz === "undefined") {
|
||||
return null;
|
||||
}
|
||||
return clazz;
|
||||
}
|
||||
|
||||
static createInstance(id, tagName) {
|
||||
let clazz = TagRegistry.idToTag.get(id);
|
||||
if (clazz === null || typeof clazz === "undefined") {
|
||||
return null;
|
||||
}
|
||||
return new clazz(tagName);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
import Tag from "./Tag.js";
|
||||
|
||||
export default class ByteArrayTag extends Tag {
|
||||
|
||||
constructor(name, value = new Uint8Array(0)) {
|
||||
super(name);
|
||||
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
write(buffer) {
|
||||
buffer.writeInt(this.value.length);
|
||||
buffer.write(this.value, this.value.length);
|
||||
}
|
||||
|
||||
read(buffer) {
|
||||
this.value = new Uint8Array(buffer.readInt());
|
||||
buffer.read(this.value, this.value.length);
|
||||
}
|
||||
|
||||
getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
setValue(value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
import Tag from "./Tag.js";
|
||||
|
||||
export default class ByteTag extends Tag {
|
||||
|
||||
constructor(name, value = 0) {
|
||||
super(name);
|
||||
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
write(buffer) {
|
||||
buffer.writeByte(this.value);
|
||||
}
|
||||
|
||||
read(buffer) {
|
||||
this.value = buffer.readByte();
|
||||
}
|
||||
|
||||
getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
setValue(value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
import Tag from "./Tag.js";
|
||||
import NBTIO from "../../NBTIO.js";
|
||||
|
||||
export default class CompoundTag extends Tag {
|
||||
|
||||
constructor(name, value = new Map()) {
|
||||
super(name);
|
||||
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
write(buffer) {
|
||||
for (let [key, tag] of this.value) {
|
||||
NBTIO.writeTag(buffer, tag);
|
||||
}
|
||||
buffer.writeByte(0);
|
||||
}
|
||||
|
||||
read(buffer) {
|
||||
let tags = [];
|
||||
let tag = null;
|
||||
while ((tag = NBTIO.readTag(buffer)) !== null) {
|
||||
tags.push(tag);
|
||||
}
|
||||
for (let tag of tags) {
|
||||
this.put(tag);
|
||||
}
|
||||
}
|
||||
|
||||
put(tag) {
|
||||
this.value.set(tag.getName(), tag);
|
||||
}
|
||||
|
||||
getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
setValue(value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
import Tag from "./Tag.js";
|
||||
|
||||
export default class DoubleTag extends Tag {
|
||||
|
||||
constructor(name, value = 0) {
|
||||
super(name);
|
||||
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
write(buffer) {
|
||||
buffer.writeDouble(this.value);
|
||||
}
|
||||
|
||||
read(buffer) {
|
||||
this.value = buffer.readDouble();
|
||||
}
|
||||
|
||||
getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
setValue(value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
import Tag from "./Tag.js";
|
||||
|
||||
export default class FloatTag extends Tag {
|
||||
|
||||
constructor(name, value = 0) {
|
||||
super(name);
|
||||
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
write(buffer) {
|
||||
buffer.writeFloat(this.value);
|
||||
}
|
||||
|
||||
read(buffer) {
|
||||
this.value = buffer.readFloat();
|
||||
}
|
||||
|
||||
getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
setValue(value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
import Tag from "./Tag.js";
|
||||
|
||||
export default class IntArrayTag extends Tag {
|
||||
|
||||
constructor(name, value = []) {
|
||||
super(name);
|
||||
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
write(buffer) {
|
||||
buffer.writeInt(this.value.length);
|
||||
for (let i = 0; i < this.value.length; i++) {
|
||||
buffer.writeInt(this.value[i]);
|
||||
}
|
||||
}
|
||||
|
||||
read(buffer) {
|
||||
this.value = new Uint8Array(buffer.readInt());
|
||||
for (let i = 0; i < this.value.length; i++) {
|
||||
this.value[i] = buffer.readInt();
|
||||
}
|
||||
}
|
||||
|
||||
getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
setValue(value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
import Tag from "./Tag.js";
|
||||
|
||||
export default class IntTag extends Tag {
|
||||
|
||||
constructor(name, value = 0) {
|
||||
super(name);
|
||||
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
write(buffer) {
|
||||
buffer.writeInt(this.value);
|
||||
}
|
||||
|
||||
read(buffer) {
|
||||
this.value = buffer.readInt();
|
||||
}
|
||||
|
||||
getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
setValue(value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
import Tag from "./Tag.js";
|
||||
import TagRegistry from "../TagRegistry.js";
|
||||
|
||||
export default class ListTag extends Tag {
|
||||
|
||||
constructor(name, type, value = []) {
|
||||
super(name);
|
||||
|
||||
this.type = type;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
write(buffer) {
|
||||
if (this.value.length === 0) {
|
||||
buffer.writeByte(0);
|
||||
} else {
|
||||
let id = TagRegistry.getIdFor(this.type);
|
||||
if (id === -1) {
|
||||
throw new Error("Unknown tag type: " + this.type);
|
||||
}
|
||||
buffer.writeByte(id);
|
||||
}
|
||||
|
||||
buffer.writeInt(this.value.length);
|
||||
for (let i = 0; i < this.value.length; i++) {
|
||||
this.value[i].write(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
read(buffer) {
|
||||
let id = buffer.readByte();
|
||||
this.type = TagRegistry.getClassFor(id);
|
||||
this.value = [];
|
||||
|
||||
let length = buffer.readInt();
|
||||
for (let i = 0; i < length; i++) {
|
||||
let tag = TagRegistry.createInstance(id, "");
|
||||
tag.read(buffer);
|
||||
this.add(tag);
|
||||
}
|
||||
}
|
||||
|
||||
add(tag) {
|
||||
this.value.push(tag);
|
||||
}
|
||||
|
||||
getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
setValue(value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
import Tag from "./Tag.js";
|
||||
|
||||
export default class LongTag extends Tag {
|
||||
|
||||
constructor(name, value = 0) {
|
||||
super(name);
|
||||
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
write(buffer) {
|
||||
buffer.writeLong(this.value);
|
||||
}
|
||||
|
||||
read(buffer) {
|
||||
this.value = buffer.readLong();
|
||||
}
|
||||
|
||||
getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
setValue(value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
import Tag from "./Tag.js";
|
||||
|
||||
export default class ShortTag extends Tag {
|
||||
|
||||
constructor(name, value = 0) {
|
||||
super(name);
|
||||
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
write(buffer) {
|
||||
buffer.writeShort(this.value);
|
||||
}
|
||||
|
||||
read(buffer) {
|
||||
this.value = buffer.readShort();
|
||||
}
|
||||
|
||||
getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
setValue(value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
import Tag from "./Tag.js";
|
||||
|
||||
export default class StringTag extends Tag {
|
||||
|
||||
constructor(name, value = "") {
|
||||
super(name);
|
||||
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
write(buffer) {
|
||||
let bytes = new TextEncoder().encode(this.value);
|
||||
buffer.writeShort(bytes.length);
|
||||
buffer.write(bytes, bytes.length);
|
||||
}
|
||||
|
||||
read(buffer) {
|
||||
let length = buffer.readShort();
|
||||
let bytes = new Uint8Array(length);
|
||||
buffer.read(bytes, length);
|
||||
this.value = new TextDecoder().decode(bytes);
|
||||
}
|
||||
|
||||
getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
setValue(value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
export default class Tag {
|
||||
constructor(name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
write(buffer) {
|
||||
|
||||
}
|
||||
|
||||
read(buffer) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
export default class MissingPackets {
|
||||
|
||||
constructor() {
|
||||
this.table = {};
|
||||
|
||||
this.map(0, "ServerKeepAlivePacket");
|
||||
this.map(1, "ServerJoinGamePacket");
|
||||
this.map(2, "ServerChatPacket");
|
||||
this.map(3, "ServerUpdateTimePacket");
|
||||
this.map(4, "ServerEntityEquipmentPacket");
|
||||
this.map(5, "ServerSpawnPositionPacket");
|
||||
this.map(6, "ServerUpdateHealthPacket");
|
||||
this.map(7, "ServerRespawnPacket");
|
||||
this.map(8, "ServerPlayerPositionRotationPacket");
|
||||
this.map(9, "ServerChangeHeldItemPacket");
|
||||
this.map(10, "ServerPlayerUseBedPacket");
|
||||
this.map(11, "ServerAnimationPacket");
|
||||
this.map(12, "ServerSpawnPlayerPacket");
|
||||
this.map(13, "ServerCollectItemPacket");
|
||||
this.map(14, "ServerSpawnObjectPacket");
|
||||
this.map(15, "ServerSpawnMobPacket");
|
||||
this.map(16, "ServerSpawnPaintingPacket");
|
||||
this.map(17, "ServerSpawnExpOrbPacket");
|
||||
this.map(18, "ServerEntityVelocityPacket");
|
||||
this.map(19, "ServerDestroyEntitiesPacket");
|
||||
this.map(20, "ServerEntityMovementPacket");
|
||||
this.map(21, "ServerEntityPositionPacket");
|
||||
this.map(22, "ServerEntityRotationPacket");
|
||||
this.map(23, "ServerEntityPositionRotationPacket");
|
||||
this.map(24, "ServerEntityTeleportPacket");
|
||||
this.map(25, "ServerEntityHeadLookPacket");
|
||||
this.map(26, "ServerEntityStatusPacket");
|
||||
this.map(27, "ServerEntityAttachPacket");
|
||||
this.map(28, "ServerEntityMetadataPacket");
|
||||
this.map(29, "ServerEntityEffectPacket");
|
||||
this.map(30, "ServerEntityRemoveEffectPacket");
|
||||
this.map(31, "ServerSetExperiencePacket");
|
||||
this.map(32, "ServerEntityPropertiesPacket");
|
||||
this.map(33, "ServerChunkDataPacket");
|
||||
this.map(34, "ServerMultiBlockChangePacket");
|
||||
this.map(35, "ServerBlockChangePacket");
|
||||
this.map(36, "ServerBlockValuePacket");
|
||||
this.map(37, "ServerBlockBreakAnimPacket");
|
||||
this.map(38, "ServerMultiChunkDataPacket");
|
||||
this.map(39, "ServerExplosionPacket");
|
||||
this.map(40, "ServerPlayEffectPacket");
|
||||
this.map(41, "ServerPlaySoundPacket");
|
||||
this.map(42, "ServerSpawnParticlePacket");
|
||||
this.map(43, "ServerNotifyClientPacket");
|
||||
this.map(44, "ServerSpawnGlobalEntityPacket");
|
||||
this.map(45, "ServerOpenWindowPacket");
|
||||
this.map(46, "ServerCloseWindowPacket");
|
||||
this.map(47, "ServerSetSlotPacket");
|
||||
this.map(48, "ServerWindowItemsPacket");
|
||||
this.map(49, "ServerWindowPropertyPacket");
|
||||
this.map(50, "ServerConfirmTransactionPacket");
|
||||
this.map(51, "ServerUpdateSignPacket");
|
||||
this.map(52, "ServerMapDataPacket");
|
||||
this.map(53, "ServerUpdateTileEntityPacket");
|
||||
this.map(54, "ServerOpenTileEntityEditorPacket");
|
||||
this.map(55, "ServerStatisticsPacket");
|
||||
this.map(56, "ServerPlayerListEntryPacket");
|
||||
this.map(57, "ServerPlayerAbilitiesPacket");
|
||||
this.map(58, "ServerTabCompletePacket");
|
||||
this.map(59, "ServerScoreboardObjectivePacket");
|
||||
this.map(60, "ServerUpdateScorePacket");
|
||||
this.map(61, "ServerDisplayScoreboardPacket");
|
||||
this.map(62, "ServerTeamPacket");
|
||||
this.map(63, "ServerPluginMessagePacket");
|
||||
this.map(64, "ServerDisconnectPacket");
|
||||
this.map(65, "ServerDifficultyPacket");
|
||||
this.map(66, "ServerCombatPacket");
|
||||
this.map(67, "ServerSwitchCameraPacket");
|
||||
this.map(68, "ServerWorldBorderPacket");
|
||||
this.map(69, "ServerTitlePacket");
|
||||
this.map(70, "ServerSetCompressionPacket");
|
||||
this.map(71, "ServerPlayerListDataPacket");
|
||||
this.map(72, "ServerResourcePackSendPacket");
|
||||
this.map(73, "ServerEntityNBTUpdatePacket");
|
||||
}
|
||||
|
||||
map(id, name) {
|
||||
this.table[id] = name;
|
||||
}
|
||||
|
||||
get(id) {
|
||||
return this.table[id];
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user