implement player spawning, movement, animation, metadata and destroying, implement NBT serialization, version 1.1.7
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user