minecraft-source/src/net/minecraft/server/level/ServerEntity.java

275 lines
13 KiB
Java

package net.minecraft.server.level;
import org.apache.logging.log4j.LogManager;
import java.util.Set;
import net.minecraft.network.syncher.SynchedEntityData;
import net.minecraft.world.entity.ai.attributes.AttributeInstance;
import java.util.Collection;
import net.minecraft.network.protocol.game.ClientboundSetEntityLinkPacket;
import net.minecraft.world.entity.Mob;
import net.minecraft.network.protocol.game.ClientboundUpdateMobEffectPacket;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.network.protocol.game.ClientboundSetEquippedItemPacket;
import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.network.protocol.game.ClientboundAddMobPacket;
import net.minecraft.network.protocol.game.ClientboundUpdateAttributesPacket;
import net.minecraft.world.entity.ai.attributes.ModifiableAttributeMap;
import net.minecraft.network.protocol.game.ClientboundSetEntityDataPacket;
import java.util.Iterator;
import net.minecraft.world.level.saveddata.maps.MapItemSavedData;
import net.minecraft.world.item.ItemStack;
import net.minecraft.network.protocol.game.ClientboundRotateHeadPacket;
import net.minecraft.network.protocol.game.ClientboundSetEntityMotionPacket;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.network.protocol.game.ClientboundTeleportEntityPacket;
import net.minecraft.world.entity.projectile.AbstractArrow;
import net.minecraft.network.protocol.game.ClientboundMoveEntityPacket;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.Level;
import net.minecraft.world.item.MapItem;
import net.minecraft.world.entity.decoration.ItemFrame;
import net.minecraft.network.protocol.game.ClientboundSetPassengersPacket;
import net.minecraft.util.Mth;
import java.util.Collections;
import java.util.List;
import net.minecraft.world.phys.Vec3;
import net.minecraft.network.protocol.Packet;
import java.util.function.Consumer;
import net.minecraft.world.entity.Entity;
import org.apache.logging.log4j.Logger;
public class ServerEntity {
private static final Logger LOGGER;
private final ServerLevel level;
private final Entity entity;
private final int updateInterval;
private final boolean trackDelta;
private final Consumer<Packet<?>> broadcast;
private long xp;
private long yp;
private long zp;
private int yRotp;
private int xRotp;
private int yHeadRotp;
private Vec3 ap;
private int tickCount;
private int teleportDelay;
private List<Entity> lastPassengers;
private boolean wasRiding;
private boolean wasOnGround;
public ServerEntity(final ServerLevel xd, final Entity akn, final int integer, final boolean boolean4, final Consumer<Packet<?>> consumer) {
this.ap = Vec3.ZERO;
this.lastPassengers = Collections.<Entity>emptyList();
this.level = xd;
this.broadcast = consumer;
this.entity = akn;
this.updateInterval = integer;
this.trackDelta = boolean4;
this.updateSentPos();
this.yRotp = Mth.floor(akn.yRot * 256.0f / 360.0f);
this.xRotp = Mth.floor(akn.xRot * 256.0f / 360.0f);
this.yHeadRotp = Mth.floor(akn.getYHeadRot() * 256.0f / 360.0f);
this.wasOnGround = akn.onGround;
}
public void sendChanges() {
final List<Entity> list2 = this.entity.getPassengers();
if (!list2.equals(this.lastPassengers)) {
this.lastPassengers = list2;
this.broadcast.accept(new ClientboundSetPassengersPacket(this.entity));
}
if (this.entity instanceof ItemFrame && this.tickCount % 10 == 0) {
final ItemFrame avo3 = (ItemFrame)this.entity;
final ItemStack bek4 = avo3.getItem();
if (bek4.getItem() instanceof MapItem) {
final MapItemSavedData crd5 = MapItem.getOrCreateSavedData(bek4, this.level);
for (final ServerPlayer xe7 : this.level.players()) {
crd5.tickCarriedBy(xe7, bek4);
final Packet<?> lt8 = ((MapItem)bek4.getItem()).getUpdatePacket(bek4, this.level, xe7);
if (lt8 != null) {
xe7.connection.send(lt8);
}
}
}
this.sendDirtyEntityData();
}
if (this.tickCount % this.updateInterval == 0 || this.entity.hasImpulse || this.entity.getEntityData().isDirty()) {
if (this.entity.isPassenger()) {
final int integer3 = Mth.floor(this.entity.yRot * 256.0f / 360.0f);
final int integer4 = Mth.floor(this.entity.xRot * 256.0f / 360.0f);
final boolean boolean5 = Math.abs(integer3 - this.yRotp) >= 1 || Math.abs(integer4 - this.xRotp) >= 1;
if (boolean5) {
this.broadcast.accept(new ClientboundMoveEntityPacket.Rot(this.entity.getId(), (byte)integer3, (byte)integer4, this.entity.onGround));
this.yRotp = integer3;
this.xRotp = integer4;
}
this.updateSentPos();
this.sendDirtyEntityData();
this.wasRiding = true;
}
else {
++this.teleportDelay;
final int integer3 = Mth.floor(this.entity.yRot * 256.0f / 360.0f);
final int integer4 = Mth.floor(this.entity.xRot * 256.0f / 360.0f);
final Vec3 cvi5 = this.entity.position().subtract(ClientboundMoveEntityPacket.packetToEntity(this.xp, this.yp, this.zp));
final boolean boolean6 = cvi5.lengthSqr() >= 7.62939453125E-6;
Packet<?> lt9 = null;
final boolean boolean7 = boolean6 || this.tickCount % 60 == 0;
final boolean boolean8 = Math.abs(integer3 - this.yRotp) >= 1 || Math.abs(integer4 - this.xRotp) >= 1;
if (this.tickCount > 0 || this.entity instanceof AbstractArrow) {
final long long10 = ClientboundMoveEntityPacket.entityToPacket(cvi5.x);
final long long11 = ClientboundMoveEntityPacket.entityToPacket(cvi5.y);
final long long12 = ClientboundMoveEntityPacket.entityToPacket(cvi5.z);
final boolean boolean9 = long10 < -32768L || long10 > 32767L || long11 < -32768L || long11 > 32767L || long12 < -32768L || long12 > 32767L;
if (boolean9 || this.teleportDelay > 400 || this.wasRiding || this.wasOnGround != this.entity.onGround) {
this.wasOnGround = this.entity.onGround;
this.teleportDelay = 0;
lt9 = new ClientboundTeleportEntityPacket(this.entity);
}
else if ((boolean7 && boolean8) || this.entity instanceof AbstractArrow) {
lt9 = new ClientboundMoveEntityPacket.PosRot(this.entity.getId(), (short)long10, (short)long11, (short)long12, (byte)integer3, (byte)integer4, this.entity.onGround);
}
else if (boolean7) {
lt9 = new ClientboundMoveEntityPacket.Pos(this.entity.getId(), (short)long10, (short)long11, (short)long12, this.entity.onGround);
}
else if (boolean8) {
lt9 = new ClientboundMoveEntityPacket.Rot(this.entity.getId(), (byte)integer3, (byte)integer4, this.entity.onGround);
}
}
if ((this.trackDelta || this.entity.hasImpulse || (this.entity instanceof LivingEntity && ((LivingEntity)this.entity).isFallFlying())) && this.tickCount > 0) {
final Vec3 cvi6 = this.entity.getDeltaMovement();
final double double11 = cvi6.distanceToSqr(this.ap);
if (double11 > 1.0E-7 || (double11 > 0.0 && cvi6.lengthSqr() == 0.0)) {
this.ap = cvi6;
this.broadcast.accept(new ClientboundSetEntityMotionPacket(this.entity.getId(), this.ap));
}
}
if (lt9 != null) {
this.broadcast.accept(lt9);
}
this.sendDirtyEntityData();
if (boolean7) {
this.updateSentPos();
}
if (boolean8) {
this.yRotp = integer3;
this.xRotp = integer4;
}
this.wasRiding = false;
}
final int integer3 = Mth.floor(this.entity.getYHeadRot() * 256.0f / 360.0f);
if (Math.abs(integer3 - this.yHeadRotp) >= 1) {
this.broadcast.accept(new ClientboundRotateHeadPacket(this.entity, (byte)integer3));
this.yHeadRotp = integer3;
}
this.entity.hasImpulse = false;
}
++this.tickCount;
if (this.entity.hurtMarked) {
this.broadcastAndSend(new ClientboundSetEntityMotionPacket(this.entity));
this.entity.hurtMarked = false;
}
}
public void removePairing(final ServerPlayer xe) {
this.entity.stopSeenByPlayer(xe);
xe.sendRemoveEntity(this.entity);
}
public void addPairing(final ServerPlayer xe) {
this.sendPairingData(xe.connection::send);
this.entity.startSeenByPlayer(xe);
xe.cancelRemoveEntity(this.entity);
}
public void sendPairingData(final Consumer<Packet<?>> consumer) {
if (this.entity.removed) {
ServerEntity.LOGGER.warn("Fetching packet for removed entity " + this.entity);
}
final Packet<?> lt3 = this.entity.getAddEntityPacket();
this.yHeadRotp = Mth.floor(this.entity.getYHeadRot() * 256.0f / 360.0f);
consumer.accept(lt3);
if (!this.entity.getEntityData().isEmpty()) {
consumer.accept(new ClientboundSetEntityDataPacket(this.entity.getId(), this.entity.getEntityData(), true));
}
boolean boolean4 = this.trackDelta;
if (this.entity instanceof LivingEntity) {
final ModifiableAttributeMap alt5 = (ModifiableAttributeMap)((LivingEntity)this.entity).getAttributes();
final Collection<AttributeInstance> collection6 = alt5.getSyncableAttributes();
if (!collection6.isEmpty()) {
consumer.accept(new ClientboundUpdateAttributesPacket(this.entity.getId(), collection6));
}
if (((LivingEntity)this.entity).isFallFlying()) {
boolean4 = true;
}
}
this.ap = this.entity.getDeltaMovement();
if (boolean4 && !(lt3 instanceof ClientboundAddMobPacket)) {
consumer.accept(new ClientboundSetEntityMotionPacket(this.entity.getId(), this.ap));
}
if (this.entity instanceof LivingEntity) {
for (final EquipmentSlot aks8 : EquipmentSlot.values()) {
final ItemStack bek9 = ((LivingEntity)this.entity).getItemBySlot(aks8);
if (!bek9.isEmpty()) {
consumer.accept(new ClientboundSetEquippedItemPacket(this.entity.getId(), aks8, bek9));
}
}
}
if (this.entity instanceof LivingEntity) {
final LivingEntity akw5 = (LivingEntity)this.entity;
for (final MobEffectInstance akh7 : akw5.getActiveEffects()) {
consumer.accept(new ClientboundUpdateMobEffectPacket(this.entity.getId(), akh7));
}
}
if (!this.entity.getPassengers().isEmpty()) {
consumer.accept(new ClientboundSetPassengersPacket(this.entity));
}
if (this.entity.isPassenger()) {
consumer.accept(new ClientboundSetPassengersPacket(this.entity.getVehicle()));
}
if (this.entity instanceof Mob) {
final Mob akx5 = (Mob)this.entity;
if (akx5.isLeashed()) {
consumer.accept(new ClientboundSetEntityLinkPacket(akx5, akx5.getLeashHolder()));
}
}
}
private void sendDirtyEntityData() {
final SynchedEntityData se2 = this.entity.getEntityData();
if (se2.isDirty()) {
this.broadcastAndSend(new ClientboundSetEntityDataPacket(this.entity.getId(), se2, false));
}
if (this.entity instanceof LivingEntity) {
final ModifiableAttributeMap alt3 = (ModifiableAttributeMap)((LivingEntity)this.entity).getAttributes();
final Set<AttributeInstance> set4 = alt3.getDirtyAttributes();
if (!set4.isEmpty()) {
this.broadcastAndSend(new ClientboundUpdateAttributesPacket(this.entity.getId(), set4));
}
set4.clear();
}
}
private void updateSentPos() {
this.xp = ClientboundMoveEntityPacket.entityToPacket(this.entity.getX());
this.yp = ClientboundMoveEntityPacket.entityToPacket(this.entity.getY());
this.zp = ClientboundMoveEntityPacket.entityToPacket(this.entity.getZ());
}
public Vec3 sentPos() {
return ClientboundMoveEntityPacket.packetToEntity(this.xp, this.yp, this.zp);
}
private void broadcastAndSend(final Packet<?> lt) {
this.broadcast.accept(lt);
if (this.entity instanceof ServerPlayer) {
((ServerPlayer)this.entity).connection.send(lt);
}
}
static {
LOGGER = LogManager.getLogger();
}
}